Setup

library("tidyverse")
library("ggpubr")
library("zoo")
setwd("/mnt/LocalData/behaviour/aDN/aDN_behaviour")



Colours …

gg_color_hue <- function(n) {
  hues = seq(15, 375, length = n + 1)
  hcl(h = hues, l = 65, c = 100)[1:n]
}
gg_color_hue(2)
[1] "#F8766D" "#00BFC4"



genotypes <- read_tsv("../2019_03_06_Courtship/genotype.tsv",col_names = TRUE)
genotypes



# indices_list <- list.files("raw data/") %>% str_subset("_Indices.csv")
indices_list <- list.files("../2019_03_06_Courtship/",recursive = TRUE) %>% str_subset("_Indices.csv") %>% str_subset("Male")
all_indices <- tibble()
for (indices_file in indices_list) {
  video_name <- indices_file %>% str_remove("/.*")
  temp <- read_csv(paste0("../2019_03_06_Courtship/",indices_file))
  temp <- temp %>%
    mutate(video = video_name)
  all_indices <- bind_rows(all_indices,temp)
}
all_indices
all_male_indices <- left_join(x = genotypes,y = all_indices,by=c("video"="video","fly_id"="FlyId"))
all_male_indices %>% 
  group_by(genotype) %>% 
  summarise(n = length(genotype))
unique(all_male_indices$genotype)
[1] "A" "B" "C" "D"



ggplot(all_male_indices,aes(x=genotype,y=CourtshipIndexWithFacing)) + 
  geom_boxplot()



p1 <- ggplot(all_male_indices,aes(x=genotype,y=CourtshipIndex)) + 
  geom_boxplot()
p2 <- ggplot(all_male_indices,aes(x=genotype,y=CourtshipIndexWithFacing)) + 
  geom_boxplot()
p3 <- ggplot(all_male_indices,aes(x=genotype,y=TotalCCI)) + 
  geom_boxplot()
p4 <- ggplot(all_male_indices,aes(x=genotype,y=TotalCCIwFacing)) + 
  geom_boxplot()
ggarrange(plotlist = list(p1,p2,p3,p4),
          # labels = c("ApproachingIndex",
          #            "ContactIndex",
          #            "EncirclingIndex",
          #            "FacingIndex",
          #            "TurningIndex",
          #            "WingIndex"),
          # hjust = 1,
          ncol = 4,
          nrow = 1)



p1 <- ggplot(all_male_indices,aes(x=genotype,y=ApproachingIndex)) + 
  geom_boxplot()
p2 <- ggplot(all_male_indices,aes(x=genotype,y=ContactIndex)) + 
  geom_boxplot()
p3 <- ggplot(all_male_indices,aes(x=genotype,y=EncirclingIndex)) + 
  geom_boxplot()
p4 <- ggplot(all_male_indices,aes(x=genotype,y=FacingIndex)) + 
  geom_boxplot()
p5 <- ggplot(all_male_indices,aes(x=genotype,y=TurningIndex)) + 
  geom_boxplot()
p6 <- ggplot(all_male_indices,aes(x=genotype,y=WingIndex)) + 
  geom_boxplot()
ggarrange(plotlist = list(p1,p2,p3,p4,p5,p6),
          # labels = c("ApproachingIndex",
          #            "ContactIndex",
          #            "EncirclingIndex",
          #            "FacingIndex",
          #            "TurningIndex",
          #            "WingIndex"),
          # hjust = 1,
          ncol = 3,
          nrow = 2)



p1 <- ggplot(all_male_indices,aes(x=genotype,y=CourtshipInitiation)) + 
  geom_boxplot()
p2 <- ggplot(all_male_indices,aes(x=genotype,y=CourtshipTermination)) + 
  geom_boxplot()
p3 <- ggplot(all_male_indices,aes(x=genotype,y=CourtshipDuration)) + 
  geom_boxplot()
ggarrange(plotlist = list(p1,p2,p3),
          ncol = 3,
          nrow = 1)



df <- all_male_indices %>%
  select(genotype,CourtshipTermination) %>% 
  group_by(genotype) %>% 
  mutate(len=length(CourtshipTermination))
#ggplot(df,aes(x=CourtshipTermination,color=genotype)) + geom_step(aes(len=len,y=..y.. * len),stat="ecdf") 
ggplot(df,aes(x=CourtshipTermination,color=genotype)) + geom_step(aes(y=..y..),stat="ecdf")



df <- all_male_indices %>%
  select(genotype,CourtshipDuration) %>% 
  group_by(genotype) %>% 
  mutate(len=length(CourtshipDuration))
#ggplot(df,aes(x=CourtshipDuration,color=genotype)) + geom_step(aes(len=len,y=..y.. * len),stat="ecdf") 
ggplot(df,aes(x=CourtshipDuration,color=genotype)) + geom_step(aes(y=..y..),stat="ecdf")



p1 <- ggplot(all_male_indices,aes(x=genotype,y=ApproachingBoutLength)) + 
  geom_boxplot()
p2 <- ggplot(all_male_indices,aes(x=genotype,y=ContactBoutLength)) + 
  geom_boxplot()
p3 <- ggplot(all_male_indices,aes(x=genotype,y=EncirclingBoutLength)) + 
  geom_boxplot()
p4 <- ggplot(all_male_indices,aes(x=genotype,y=FacingBoutLength)) + 
  geom_boxplot()
p5 <- ggplot(all_male_indices,aes(x=genotype,y=TurningBoutLength)) + 
  geom_boxplot()
p6 <- ggplot(all_male_indices,aes(x=genotype,y=WingBoutLength)) + 
  geom_boxplot()
p7 <- ggplot(all_male_indices,aes(x=genotype,y=ApproachingBoutInterval)) + 
  geom_boxplot()
p8 <- ggplot(all_male_indices,aes(x=genotype,y=ContactBoutInterval)) + 
  geom_boxplot()
p9 <- ggplot(all_male_indices,aes(x=genotype,y=EncirclingBoutInterval)) + 
  geom_boxplot()
p10 <- ggplot(all_male_indices,aes(x=genotype,y=FacingBoutInterval)) + 
  geom_boxplot()
p11 <- ggplot(all_male_indices,aes(x=genotype,y=TurningBoutInterval)) + 
  geom_boxplot()
p12 <- ggplot(all_male_indices,aes(x=genotype,y=WingBoutInterval)) + 
  geom_boxplot()
ggarrange(plotlist = list(p1,p2,p3,p4,p5,p6,
                          p7,p8,p9,p10,p11,p12),
          # labels = c("ApproachingIndex",
          #            "ContactIndex",
          #            "EncirclingIndex",
          #            "FacingIndex",
          #            "TurningIndex",
          #            "WingIndex"),
          # hjust = 1,
          ncol = 6,
          nrow = 2)





rawdata_list <- list.files("../",recursive = TRUE) %>% str_subset("_ALLDATA.csv") %>% str_subset("_Male_")
all_rawdata <- tibble()
for (rawdata_file in rawdata_list) {
  temp <- read_csv(paste0("../",rawdata_file),progress = FALSE)
  all_rawdata <- bind_rows(all_rawdata,temp)
}
#all_rawdata <- full_join(x = all_rawdata, y = genotypes, by = c("FileName"="video","Id"="fly_id"))
all_rawdata <- all_rawdata %>%
  full_join(x = all_rawdata, y = genotypes, by = c("FileName"="video","Id"="fly_id")) %>% 
  replace_na(list(genotype = "CS female"))
# sum(is.na(all_rawdata$genotype))
# summary(all_rawdata$genotype)
# unique(all_rawdata$genotype)
all_rawdata



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Arena == 2) %>% 
  filter(Id == 3) %>% 
  filter(dist_to_other__mm > 2) %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=wing_l_ang__rad, colour = "#F8766D")) +
    geom_point(aes(y=wing_r_ang__rad, colour = "#00BFC4"))

NA



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Arena == 2) %>% 
  filter(Id == 3) %>% 
  filter(dist_to_other__mm > 2) %>% 
  ggplot() +
    geom_density(aes(x=wing_l_ang__rad, colour = "#F8766D"),size = 2) +
    geom_density(aes(x=wing_r_ang__rad, colour = "#00BFC4"),size = 2)



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Arena == 2) %>% 
  filter(Id == 3) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>% 
  ggplot() +
    geom_density(aes(x=wing_l_ang__rad, colour = "#F8766D"),size = 2) +
    geom_density(aes(x=wing_r_ang__rad, colour = "#00BFC4"),size = 2)

# # Extract density data to average
# p <- ggplot_build(test_plot)
# ggplot(as.data.frame(p$data[[1]]), aes(x,y)) + geom_line()
# ggplot(as.data.frame(p$data[[2]]), aes(x,y)) + geom_line()



all_rawdata %>% 
  filter(genotype == "A") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=max_wing_ang__rad,colour=individual)) +
    geom_density() + theme(legend.position = "none")



all_rawdata %>% 
  filter(genotype == "B") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=max_wing_ang__rad,colour=individual)) +
    geom_density() + theme(legend.position = "none")



all_rawdata %>% 
  filter(genotype == "C") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=max_wing_ang__rad,colour=individual)) +
    geom_density() + theme(legend.position = "none")



all_rawdata %>% 
  filter(genotype == "D") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=max_wing_ang__rad,colour=individual)) +
    geom_density() + theme(legend.position = "none")



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 3) %>% 
  ggplot(aes(x=Frame,y=angle_between__rad)) +
    geom_point()



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Arena == 2) %>% 
  ggplot(aes(x=Frame,y=facing_angle__rad, color=as_factor(Id))) +
    geom_point()



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Arena == 2) %>% 
  ggplot() +
    geom_density(aes(x=facing_angle__rad, color=as_factor(Id)),size = 2)



all_rawdata %>% 
  filter(unique_fly == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_6_17") %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(SmoothedDistToOther>0.5,"not copulating","copulating"))))+
    geom_point(aes(y=c(ifelse(SmoothedCopulation==1,SmoothedCopulation+6,NA))))+
    geom_point(aes(y=c(ifelse(Copulation==1,Copulation+7,NA))))
Warning messages:
1: Unknown or uninitialised column: 'bin_max_wing'. 
2: Unknown or uninitialised column: 'bin_max_wing'. 
3: Unknown or uninitialised column: 'WingGesture'. 
4: Unknown or uninitialised column: 'WingGesture'. 
5: Unknown or uninitialised column: 'bin_max_wing'. 
6: Unknown or uninitialised column: 'bin_max_wing'. 
7: Unknown or uninitialised column: 'WingGesture'. 
8: Unknown or uninitialised column: 'WingGesture'. 

all_rawdata %>% 
  filter(unique_fly == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_9_39") %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(SmoothedDistToOther>0.5,"not copulating","copulating"))))+
    geom_point(aes(y=c(ifelse(SmoothedCopulation==1,SmoothedCopulation+6,NA))))+
    geom_point(aes(y=c(ifelse(Copulation==1,Copulation+7,NA))))

all_rawdata %>% 
  filter(genotype == "B") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=facing_angle__rad,colour=individual)) +
    geom_density() + theme(legend.position = "none") +
    ylim(0,6)

all_rawdata %>% 
  filter(genotype == "C") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=facing_angle__rad,colour=individual)) +
    geom_density() + theme(legend.position = "none") +
    ylim(0,6)



all_rawdata %>% 
  filter(genotype == "D") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=facing_angle__rad,colour=individual)) +
    geom_density() + theme(legend.position = "none") +
    ylim(0,6)



all_rawdata %>% 
  filter(genotype == "A") %>% 
  filter(dist_to_other__mm > 2) %>% 
  #filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=facing_angle__rad,colour=individual)) +
    geom_density() + theme(legend.position = "none") +
    ylim(0,6)



all_rawdata %>% 
  filter(genotype == "D") %>% 
  filter(dist_to_other__mm > 2) %>% 
  #filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=facing_angle__rad,colour=individual)) +
    geom_density() + theme(legend.position = "none") +
    ylim(0,6)



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Arena == 2) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm, color=dist_to_other__mm)) +
    geom_point() 



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 3) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(dist_to_other__mm>2,"not copulating","copulating"))))





D genotype distance to other

all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 27) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(dist_to_other__mm>2,"not copulating","copulating"))))



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 29) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(dist_to_other__mm>2,"not copulating","copulating"))))



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 35) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(dist_to_other__mm>2,"not copulating","copulating"))))



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 37) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(dist_to_other__mm>2,"not copulating","copulating"))))



all_rawdata <- all_rawdata %>%  
  unite("unique_fly",FileName,Id, remove = FALSE) %>% 
  group_by(unique_fly) %>% 
  mutate(
    Multitasking = (Approaching + Encircling + Contact + Turning + WingGesture),
    MultitaskingWithFacing = (Approaching + Encircling + Facing + Contact + Turning + WingGesture),
    Courtship = ifelse(Multitasking>=1, 1, 0),
    CourtshipWithFacing = ifelse(MultitaskingWithFacing>=1, 1, 0),
    MultitaskingWithCopulation = (Approaching + Encircling + Contact + Turning + WingGesture + Copulation),
    MultitaskingWithCopulationWithFacing = (Approaching + Encircling + Facing + Contact + Turning + WingGesture + Copulation),
    CourtshipAndCopulation = ifelse(MultitaskingWithCopulation>=1, 1, 0),
    CourtshipAndCopulationWthFacing = ifelse(MultitaskingWithCopulationWithFacing>=1, 1, 0),
    SmoothedCourtship = ifelse((rollmean(Courtship, 150, fill = c(0,0,0), align = c("left")))>0.5, 1, 0),
    SmoothedCopulation = ifelse((rollmean(Copulation, 1250, fill = c(0,0,0), align = c("center")))>0.5, 1, 0),
    SmoothedDistToOther = ifelse((rollmean(ifelse(dist_to_other__mm > 2, 1, 0), 250, fill = c(1,1,NA), align = c("center")))>0.5, 1, 0)
)



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 37) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(SmoothedDistToOther==1,"not copulating","copulating"))))



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 37) %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=SmoothedDistToOther, colour = "#F8766D")) +
    geom_point(aes(y=(SmoothedCopulation+0.1), colour= "#00BFC4"))

NA



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 35) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(SmoothedDistToOther==1,"not copulating","copulating"))))



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 35) %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=SmoothedDistToOther, colour = "#F8766D")) +
    geom_point(aes(y=(SmoothedCopulation+0.1), colour= "#00BFC4"))

NA



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 35) %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=SmoothedDistToOther, colour = "#F8766D")) +
    geom_point(aes(y=(SmoothedCopulation+0.1), colour= "#00BFC4")) +
    xlim(2000,3000)



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 35) %>% 
  summarise(which.min(SmoothedDistToOther),
            which.max(SmoothedCopulation))



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 3) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(SmoothedDistToOther==1,"not copulating","copulating"))))



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 3) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(SmoothedCopulation==0,"not copulating","copulating"))))



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 3) %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=SmoothedDistToOther, colour = "#F8766D")) +
    geom_point(aes(y=(SmoothedCopulation+0.1), colour= "#00BFC4")) +
    xlim(6000,7000)



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 3) %>% 
  summarise(which.min(SmoothedDistToOther),
            which.max(SmoothedCopulation))





D genotype distance to other

all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 27) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(SmoothedDistToOther==1,"not copulating","copulating"))))



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 29) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(SmoothedDistToOther==1,"not copulating","copulating"))))



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 35) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(SmoothedDistToOther>0.5,"not copulating","copulating"))))



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 37) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(SmoothedDistToOther==1,"not copulating","copulating"))))





all_rawdata %>% 
  filter(genotype == "D") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=max_wing_ang__rad,colour=individual)) +
    geom_density() + theme(legend.position = "none") +
    ylim(0,6) +
    xlim(0,pi)



all_rawdata %>% 
  filter(genotype == "A") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=angle_between__rad,colour=individual)) +
    geom_density() + theme(legend.position = "none") +
    ylim(0,3) +
    xlim(0,pi)



all_rawdata %>% 
  filter(genotype == "D") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=angle_between__rad,colour=individual)) +
    geom_density() + theme(legend.position = "none") +
    ylim(0,3) +
    xlim(0,pi)



Distance to wall

all_rawdata %>% 
  filter(genotype == "A") %>% 
  filter(dist_to_other__mm > 2) %>% 
  #filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=dist_to_wall__mm,colour=individual)) +
    geom_density() + theme(legend.position = "none") +
    ylim(0,2.2) +
    xlim(0,10)



all_rawdata %>% 
  filter(genotype == "D") %>% 
  filter(dist_to_other__mm > 2) %>% 
  #filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=dist_to_wall__mm,colour=individual)) +
    geom_density() + theme(legend.position = "none") +
    ylim(0,2.2) +
    xlim(0,10)



p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            mean_dist_to_wall_mm = mean(dist_to_wall__mm[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        (which.max(SmoothedCourtship)+(25*600))),
                                                                                  (which.max(SmoothedCourtship)+(25*600))
                                                                                  )
                                             ]
                                 )
            ) %>% 
  ggplot(aes(x=genotype,y=mean_dist_to_wall_mm)) +
    geom_boxplot()
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            median_dist_to_wall_mm = median(dist_to_wall__mm[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        (which.max(SmoothedCourtship)+(25*600))),
                                                                                  (which.max(SmoothedCourtship)+(25*600))
                                                                                  )
                                             ]
                                 )
            ) %>% 
  ggplot(aes(x=genotype,y=median_dist_to_wall_mm)) +
    geom_boxplot()
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            prop_dist_to_wall_lt_1 = 100*sum(dist_to_wall__mm[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        (which.max(SmoothedCourtship)+(25*600))),
                                                                                  (which.max(SmoothedCourtship)+(25*600))
                                                                                  )
                                             ]<1,
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        (which.max(SmoothedCourtship)+(25*600))),
                                                                                  (which.max(SmoothedCourtship)+(25*600))
                                                                                  )
                                             ]
                     )) %>% 
  ggplot(aes(x=genotype,y=prop_dist_to_wall_lt_1)) +
    geom_boxplot()
ggarrange(plotlist = list(p1,p2,p3),
          labels = c("Mean Distance to Wall",
                     "Median Distance to Wall",
                     "Prop Time Close to Wall"),
          hjust = -0.2,
          ncol = 3,
          nrow = 1)

all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  filter(dist_to_other__mm > 2) %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  ggplot(aes(x=pos_x__px,y=pos_y__px)) +
    geom_point()

all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) %>% 
  filter(dist_to_other__mm > 2) %>% 
  ggplot(aes(x=pos_x__px,y=pos_y__px)) +
    geom_point() +
    coord_fixed()

all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_wall__mm > 1) %>% 
  ggplot(aes(x=pos_x__px,y=pos_y__px)) +
    geom_point() +
    coord_fixed()

p1 <- all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) %>% 
  #filter(dist_to_other__mm > 2) %>% 
  #filter(dist_to_wall__mm > 1) %>% 
  ggplot(aes(x=genotype,y=dist_to_wall__mm)) +
    geom_boxplot() +
  ylim(0,10)
p2 <- all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) %>% 
  filter(dist_to_other__mm > 2) %>% 
  #filter(dist_to_wall__mm > 1) %>% 
  ggplot(aes(x=genotype,y=dist_to_wall__mm)) +
    geom_boxplot() +
  ylim(0,10)
p3 <- all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) %>% 
  #filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_wall__mm > 1) %>% 
  ggplot(aes(x=genotype,y=dist_to_wall__mm)) +
    geom_boxplot() +
  ylim(0,10)
p4 <- all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_wall__mm > 1) %>% 
  ggplot(aes(x=genotype,y=dist_to_wall__mm)) +
    geom_boxplot() +
  ylim(0,10)
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c("all frames",
                     "non cop frames",
                     "gt 1mm from wall",
                     "non cop, gt 1mm"),
          hjust = -0.4,
          ncol = 4,
          nrow = 1)



all_rawdata %>% 
  filter(genotype == "A") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=dist_to_other__mm,colour=individual)) +
    geom_density() + theme(legend.position = "none") +
    ylim(0,2) +
    xlim(0,20)



all_rawdata %>% 
  filter(genotype == "B") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=dist_to_other__mm,colour=individual)) +
    geom_density() + theme(legend.position = "none") +
    ylim(0,2) +
    xlim(0,20)



all_rawdata %>% 
  filter(genotype == "C") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=dist_to_other__mm,colour=individual)) +
    geom_density() + theme(legend.position = "none") +
    ylim(0,2) +
    xlim(0,20)



all_rawdata %>% 
  filter(genotype == "D") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  ggplot(aes(x=dist_to_other__mm,colour=individual)) +
    geom_density() + theme(legend.position = "none") +
    ylim(0,2) +
    xlim(0,20)



all_rawdata %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  summarise(mean_dist_to_other = mean(dist_to_other__mm))





mean distance to other

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  #filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_dist_to_other = mean(dist_to_other__mm),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_dist_to_other)) +
    geom_boxplot() +
    ylim(0,10)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_dist_to_other = mean(dist_to_other__mm),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_dist_to_other)) +
    geom_boxplot() +
    ylim(0,10)
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad < (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_dist_to_other = mean(dist_to_other__mm),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_dist_to_other)) +
    geom_boxplot() +
    ylim(0,10)
ggarrange(plotlist = list(p1,p2,p3),
          labels = c("All Frames","Wing Extension Frames","Non-Wing Extension Frames"),
          #hjust = 1,
          ncol = 3,
          nrow = 1)





median distance to other

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  #filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_dist_to_other = median(dist_to_other__mm),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_dist_to_other)) +
    geom_boxplot() +
    ylim(0,10)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_dist_to_other = median(dist_to_other__mm),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_dist_to_other)) +
    geom_boxplot() +
    ylim(0,10)
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad < (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_dist_to_other = median(dist_to_other__mm),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_dist_to_other)) +
    geom_boxplot() +
    ylim(0,10)
ggarrange(plotlist = list(p1,p2,p3),
          labels = c("All Frames","Wing Extension Frames","Non-Wing Extension Frames"),
          hjust = -0.4,
          ncol = 3,
          nrow = 1)





mean facing angle

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  #filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi)
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad < (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi)
ggarrange(plotlist = list(p1,p2,p3),
          labels = c("All Frames","Wing Extension Frames","Non-Wing Extension Frames"),
          #hjust = 1,
          ncol = 3,
          nrow = 1)





median facing angle

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  #filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_facing_angle = median(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_facing_angle = median(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi)
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad < (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_facing_angle = median(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi)
ggarrange(plotlist = list(p1,p2,p3),
          labels = c("All Frames","Wing Extension Frames","Non-Wing Extension Frames"),
          #hjust = 1,
          ncol = 3,
          nrow = 1)



p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  #filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_facing_angle = median(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_facing_angle)) +
    geom_boxplot() +
    ylim(0,1.5)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_facing_angle = median(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_facing_angle)) +
    geom_boxplot() +
    ylim(0,1)
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad < (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_facing_angle = median(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_facing_angle)) +
    geom_boxplot() +
    ylim(0,2)
ggarrange(plotlist = list(p1,p2,p3),
          labels = c("All Frames","Wing Extension Frames","Non-Wing Extension Frames"),
          #hjust = 1,
          ncol = 3,
          nrow = 1)



test_stat_tibble0 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  #filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_facing_angle = median(facing_angle__rad),
            genotype = unique(genotype))
aov0 <- aov(median_facing_angle~genotype,data = test_stat_tibble0)
summary(aov0)
             Df Sum Sq Mean Sq F value Pr(>F)  
genotype      3  1.036  0.3453   2.736 0.0468 *
Residuals   114 14.388  0.1262                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(aov0)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = median_facing_angle ~ genotype, data = test_stat_tibble0)

$genotype
           diff           lwr       upr     p adj
B-A -0.07051500 -0.3361762470 0.1951462 0.8999385
C-A  0.04970748 -0.1803176760 0.2797326 0.9426712
D-A  0.19276677 -0.0389146073 0.4244482 0.1380793
C-B  0.12022248 -0.1408020849 0.3812470 0.6275505
D-B  0.26328177  0.0007965104 0.5257670 0.0490063
D-C  0.14305929 -0.0832904123 0.3694090 0.3562046





median facing angle by sector

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad < pi/6) %>% 
  #filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_facing_angle = median(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi/6)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad < pi/6) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_facing_angle = median(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi/6)
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad < pi/6) %>% 
  filter(max_wing_ang__rad < (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_facing_angle = median(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi/6)
p4 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > pi/6) %>% 
  #filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_facing_angle = median(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi)
p5 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > pi/6) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_facing_angle = median(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi)
p6 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > pi/6) %>% 
  filter(max_wing_ang__rad < (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(median_facing_angle = median(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=median_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi)
ggarrange(plotlist = list(p1,p2,p3,p4,p5,p6),
          labels = c("All Frames","Wing Extension Frames","Non-Wing Extension Frames"),
          #hjust = 1,
          ncol = 3,
          nrow = 2)





mean facing angle by sector

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad < pi/6) %>% 
  #filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi/6)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad < pi/6) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi/6)
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad < pi/6) %>% 
  filter(max_wing_ang__rad < (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi/6)
p4 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > pi/6) %>% 
  #filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi)
p5 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > pi/6) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi)
p6 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > pi/6) %>% 
  filter(max_wing_ang__rad < (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() +
    ylim(0,pi)
ggarrange(plotlist = list(p1,p2,p3,p4,p5,p6),
          labels = c("All Frames","Wing Extension Frames","Non-Wing Extension Frames"),
          #hjust = 1,
          ncol = 3,
          nrow = 2)





mean facing angle by wee sectors

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > 0) %>% 
  filter(facing_angle__rad <= pi/6) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > pi/6) %>% 
  filter(facing_angle__rad <= 2*pi/6) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > 2*pi/6) %>% 
  filter(facing_angle__rad <= 3*pi/6) %>% 
  filter(max_wing_ang__rad < (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
p4 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > 3*pi/6) %>% 
  filter(facing_angle__rad <= 4*pi/6) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() #+
    #ylim(0,pi)
p5 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > 4*pi/6) %>% 
  filter(facing_angle__rad <= 5*pi/6) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() #+
    #ylim(0,pi)
p6 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > 5*pi/6) %>% 
  filter(facing_angle__rad <= 6*pi/6) %>% 
  filter(max_wing_ang__rad < (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(mean_facing_angle = mean(facing_angle__rad),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=mean_facing_angle)) +
    geom_boxplot() #+
    #ylim(0,pi)
ggarrange(plotlist = list(p1,p2,p3,p4,p5,p6),
          labels = c("0-pi/6","pi/6-2pi/6","2pi/6-3pi/6",
                     "3pi/6-4pi/6","4pi/6-5pi/6","5pi/6-6pi/6"),
          #hjust = 1,
          ncol = 3,
          nrow = 2)





counts in wee sectors

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > 0) %>% 
  filter(facing_angle__rad <= pi/6) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > pi/6) %>% 
  filter(facing_angle__rad <= 2*pi/6) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > 2*pi/6) %>% 
  filter(facing_angle__rad <= 3*pi/6) %>% 
  filter(max_wing_ang__rad < (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
p4 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > 3*pi/6) %>% 
  filter(facing_angle__rad <= 4*pi/6) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi)
p5 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > 4*pi/6) %>% 
  filter(facing_angle__rad <= 5*pi/6) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi)
p6 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > 5*pi/6) %>% 
  filter(facing_angle__rad <= 6*pi/6) %>% 
  filter(max_wing_ang__rad < (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi)
ggarrange(plotlist = list(p1,p2,p3,p4,p5,p6),
          labels = c("0-pi/6","pi/6-2pi/6","2pi/6-3pi/6",
                     "3pi/6-4pi/6","4pi/6-5pi/6","5pi/6-6pi/6"),
          #hjust = 1,
          ncol = 3,
          nrow = 2)





Total time in sector

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > 0) %>% 
  filter(facing_angle__rad <= pi/8) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(facing_angle__rad > pi/8) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
ggarrange(plotlist = list(p1,p2),
          labels = c("<pi/8",">pi/8"),
          hjust = -0.6,
          vjust = 2,
          ncol = 2,
          nrow = 1)





Proportion time in sector

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = 100*sum(facing_angle__rad <= pi/8)/length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = 100*sum(facing_angle__rad > pi/8)/length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
ggarrange(plotlist = list(p1,p2),
          labels = c("<pi/8",">pi/8"),
          hjust = -1.4,
          vjust = 2,
          ncol = 2,
          nrow = 1)



test_stat_tibble0 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  group_by(unique_fly) %>% 
  summarise(counts = 100*sum(facing_angle__rad > pi/8)/length(Frame),
            genotype = unique(genotype))
aov0 <- aov(counts~genotype,data = test_stat_tibble0)
#summary(aov0)
TukeyHSD(aov0)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = counts ~ genotype, data = test_stat_tibble0)

$genotype
          diff        lwr       upr     p adj
B-A  6.6367127 -2.5650354 15.838461 0.2421768
C-A  7.3146600 -0.6527555 15.282076 0.0840396
D-A 16.6152204  8.5904380 24.640003 0.0000022
C-B  0.6779474 -8.3631993  9.719094 0.9973376
D-B  9.9785077  0.8867666 19.070249 0.0254776
D-C  9.3005603  1.4604520 17.140669 0.0131217



pairwise.t.test(test_stat_tibble0$counts, test_stat_tibble0$genotype)

    Pairwise comparisons using t tests with pooled SD 

data:  test_stat_tibble0$counts and test_stat_tibble0$genotype 

  A       B     C    
B 0.125   -     -    
C 0.055   0.845 -    
D 2.2e-06 0.020 0.012

P value adjustment method: holm 



p1 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "A") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,20) + 
  scale_fill_continuous(type = "viridis",limits = c(2,2000),na.value = "white") +
  coord_polar() +
  theme_void()
p2 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "B") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,20) + 
  scale_fill_continuous(type = "viridis",limits = c(2,2000),na.value = "white") +
  coord_polar() +
  theme_void()
p3 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "C") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,20) + 
  scale_fill_continuous(type = "viridis",limits = c(2,2000),na.value = "white") +
  coord_polar() +
  theme_void()
p4 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "D") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,20) + 
  scale_fill_continuous(type = "viridis",limits = c(2,2000),na.value = "white") +
  coord_polar() +
  theme_void()
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c("A","B","C","D"),
          #hjust = 1,
          ncol = 2,
          nrow = 2)





Total time in sector

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(facing_angle__rad > 0) %>% 
  filter(facing_angle__rad <= pi/8) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(facing_angle__rad > pi/8) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
ggarrange(plotlist = list(p1,p2),
          labels = c("<pi/8",">pi/8"),
          hjust = -0.6,
          vjust = 2,
          ncol = 2,
          nrow = 1)





Proportion time in sector and within 10mm

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = 100*sum(facing_angle__rad <= pi/8)/length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = 100*sum(facing_angle__rad > pi/8)/length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
ggarrange(plotlist = list(p1,p2),
          labels = c("<pi/8",">pi/8"),
          hjust = -1.4,
          vjust = 2,
          ncol = 2,
          nrow = 1)



test_stat_tibble0 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  group_by(unique_fly) %>% 
  summarise(counts = 100*sum(facing_angle__rad > pi/8)/length(Frame),
            genotype = unique(genotype))
aov0 <- aov(counts~genotype,data = test_stat_tibble0)
#summary(aov0)
TukeyHSD(aov0)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = counts ~ genotype, data = test_stat_tibble0)

$genotype
          diff        lwr       upr     p adj
B-A  4.2169183 -3.2364908 11.670328 0.4558215
C-A  4.8104624 -1.6431383 11.264063 0.2159140
D-A 11.2681432  4.7680753 17.768211 0.0000889
C-B  0.5935441 -6.7297782  7.916866 0.9966463
D-B  7.0512248 -0.3130788 14.415528 0.0658244
D-C  6.4576807  0.1071987 12.808163 0.0446836



pairwise.t.test(test_stat_tibble0$counts, test_stat_tibble0$genotype)

    Pairwise comparisons using t tests with pooled SD 

data:  test_stat_tibble0$counts and test_stat_tibble0$genotype 

  A       B     C    
B 0.286   -     -    
C 0.163   0.833 -    
D 9.1e-05 0.056 0.046

P value adjustment method: holm 





p1 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "A") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(0,2000),na.value = "white") +
  theme_void() +
  coord_polar()
p2 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "B") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(0,2000),na.value = "white") +
  theme_void() +
  coord_polar()
p3 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "C") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(0,2000),na.value = "white") +
  theme_void() +
  coord_polar()
p4 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "D") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(0,2000),na.value = "white") +
  theme_void() +
  coord_polar()
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c("A","B","C","D"),
          #hjust = 1,
          ncol = 2,
          nrow = 2)



p1 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "A") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(4,2000),na.value = "white") +
  theme_void() +
  coord_polar()
p2 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "B") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(4,2000),na.value = "white") +
  theme_void() +
  coord_polar()
p3 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "C") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(4,2000),na.value = "white") +
  theme_void() +
  coord_polar()
p4 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "D") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(4,2000),na.value = "white") +
  theme_void() +
  coord_polar()
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c("A","B","C","D"),
          #hjust = 1,
          ncol = 2,
          nrow = 2)



p1 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "A") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(40,10)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(50,50000),na.value = "white") +
  theme_void() +
  coord_polar()
p2 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "B") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(40,10)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(50,50000),na.value = "white") +
  theme_void() +
  coord_polar()
p3 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "C") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(40,10)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(50,50000),na.value = "white") +
  theme_void() +
  coord_polar()
p4 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "D") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(40,10)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(50,50000),na.value = "white") +
  theme_void() +
  coord_polar()
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c("A","B","C","D"),
          #hjust = 1,
          ncol = 2,
          nrow = 2)



p1 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "A") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(100,25)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(10,2000),na.value = "white") +
  theme_void() +
  coord_polar()
p2 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "B") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(100,25)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(10,2000),na.value = "white") +
  theme_void() +
  coord_polar()
p3 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "C") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(100,25)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(10,2000),na.value = "white") +
  theme_void() +
  coord_polar()
p4 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "D") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  geom_bin2d(bins = c(100,25)) +
  xlim(0,2*pi) +
  ylim(0,10) + 
  scale_fill_continuous(type = "viridis",limits = c(10,2000),na.value = "white") +
  theme_void() +
  coord_polar()
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c("A","B","C","D"),
          #hjust = 1,
          ncol = 2,
          nrow = 2)



p1 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "A") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  stat_density_2d(aes(fill = ..level..), geom = "polygon", colour="white") +
  xlim(0,2*pi) +
  ylim(0,6) + 
  #scale_fill_continuous(type = "viridis",limits = c(2,2000),na.value = "white") +
  theme_grey() +
  coord_polar()
  
p2 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "B") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  stat_density_2d(aes(fill = ..level..), geom = "polygon", colour="white") +
  xlim(0,2*pi) +
  ylim(0,6) + 
  #scale_fill_continuous(type = "viridis",limits = c(2,2000),na.value = "white") +
  theme_grey() +
  coord_polar()
p3 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "C") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  stat_density_2d(aes(fill = ..level..), geom = "polygon", colour="white") +
  xlim(0,2*pi) +
  ylim(0,6) + 
  #scale_fill_continuous(type = "viridis",limits = c(2,2000),na.value = "white") +
  theme_grey() +
  coord_polar()
p4 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  filter(genotype == "D") %>% 
  ggplot(aes(x=facing_angle__rad, y=dist_to_other__mm)) +
  stat_density_2d(aes(fill = ..level..), geom = "polygon", colour="white") +
  xlim(0,2*pi) +
  ylim(0,6) + 
  #scale_fill_continuous(type = "viridis",limits = c(2,2000),na.value = "white") +
  theme_grey() +
  coord_polar()
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c("A","B","C","D"),
          #hjust = 1,
          ncol = 2,
          nrow = 2)





Total count in inner ring

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(facing_angle__rad <= pi/8) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm <= 3) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(facing_angle__rad <= pi/8) %>% 
  filter(dist_to_other__mm > 3) %>% 
  filter(dist_to_other__mm <= 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
ggarrange(plotlist = list(p1,p2),
          labels = c("2mm-3mm","3mm-10mm"),
          hjust = -0.6,
          vjust = 2,
          ncol = 2,
          nrow = 1)





Proportion count in inner ring

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(facing_angle__rad <= pi/8) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = 100*sum(dist_to_other__mm > 2 & dist_to_other__mm <= 3)/length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  filter(facing_angle__rad <= pi/8) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  unite("individual", FileName:Id, remove = FALSE) %>% 
  group_by(individual) %>% 
  summarise(counts = 100*sum(dist_to_other__mm > 3 & dist_to_other__mm <= 10)/length(Frame),
            genotype = unique(genotype)) %>% 
  ggplot(aes(x=genotype, y=counts)) +
    geom_boxplot() #+
    #ylim(0,pi/6)
ggarrange(plotlist = list(p1,p2),
          labels = c("2mm-3mm","3mm-10mm"),
          hjust = -0.6,
          vjust = 2,
          ncol = 2,
          nrow = 1)



test_stat_tibble0 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  filter(facing_angle__rad <= pi/8) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  group_by(unique_fly) %>% 
  summarise(counts = 100*sum(dist_to_other__mm > 2 & dist_to_other__mm <= 3)/length(Frame),
            genotype = unique(genotype))
aov0 <- aov(counts~genotype,data = test_stat_tibble0)
#summary(aov0)
TukeyHSD(aov0)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = counts ~ genotype, data = test_stat_tibble0)

$genotype
          diff        lwr      upr     p adj
B-A  2.7255382  -8.488600 13.93968 0.9209524
C-A  2.5367905  -7.173071 12.24665 0.9040570
D-A 21.8215793  12.041805 31.60135 0.0000003
C-B -0.1887477 -11.207161 10.82967 0.9999678
D-B 19.0960411   8.015968 30.17611 0.0000986
D-C 19.2847888   9.730076 28.83950 0.0000040







Left vs Right wing

p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            wing_index = 100*sum(WingGesture[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        (which.max(SmoothedCourtship)+(25*600))),
                                                                                  (which.max(SmoothedCourtship)+(25*600))
                                                                                  )
                                             ]
                                 )/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        (which.max(SmoothedCourtship)+(25*600))),
                                                                                  (which.max(SmoothedCourtship)+(25*600))
                                                                                  )
                                             ]
                     )) %>% 
  ggplot(aes(x=genotype,y=wing_index)) +
    geom_boxplot()
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            wing_index = 100*sum(max_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        (which.max(SmoothedCourtship)+(25*600))),
                                                                                  (which.max(SmoothedCourtship)+(25*600))
                                                                                  )
                                             ]>(35*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        (which.max(SmoothedCourtship)+(25*600))),
                                                                                  (which.max(SmoothedCourtship)+(25*600))
                                                                                  )
                                             ]
                     )) %>%
  ggplot(aes(x=genotype,y=wing_index)) +
    geom_boxplot()
ggarrange(plotlist = list(p1,p2),
          labels = c("JAABA","wing angle"),
          hjust = -0.6,
          vjust = 2,
          ncol = 2,
          nrow = 1)



all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            Wing_index_by_JAABA = 100*sum(WingGesture[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                                 )/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     ),
            Wing_index_by_angle = 100*sum(max_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]>(35*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     )) %>%
  ggplot(aes(x=Wing_index_by_angle,y=Wing_index_by_JAABA,colour=genotype)) +
    geom_point() +
    geom_smooth(method=lm) +
    stat_cor(label.y = c(52,56,60,64), size =5) +
    stat_regline_equation(label.y = c(50,54,58,62), size =5) +
    coord_fixed()



wind <- 600
p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            wing_index = 100*sum(max_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]>(35*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     )) %>% 
  ggplot(aes(x=genotype,y=wing_index)) +
    geom_boxplot()
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            left_wing_index = 100*sum(wing_l_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]<(-35*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     )) %>%
  ggplot(aes(x=genotype,y=left_wing_index)) +
    geom_boxplot()
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            right_wing_index = 100*sum(wing_r_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]>(35*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     )) %>%
  ggplot(aes(x=genotype,y=right_wing_index)) +
    geom_boxplot()
p4 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            both_wing_index = 100*sum(min_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]>(35*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     )) %>%
  ggplot(aes(x=genotype,y=both_wing_index)) +
    geom_boxplot()
ggarrange(plotlist = list(p1,p4,p2,p3),
          labels = c("either wing","both wings","left wing","right wing"),
          hjust = -0.6,
          vjust = 2,
          ncol = 2,
          nrow = 2)



test_stat_tibble <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  #filter(genotype != "A") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            both_wing_index = 100*sum(min_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]>(35*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     ))
aov1 <- aov(both_wing_index~genotype, data = test_stat_tibble)
TukeyHSD(aov1)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = both_wing_index ~ genotype, data = test_stat_tibble)

$genotype
          diff        lwr      upr     p adj
B-A -0.4779248 -2.0714700 1.115620 0.8624926
C-A -0.1148557 -1.4946410 1.264930 0.9963700
D-A  0.8787432 -0.5109769 2.268463 0.3557950
C-B  0.3630691 -1.2026635 1.928802 0.9304240
D-B  1.3566679 -0.2178265 2.931162 0.1170595
D-C  0.9935989 -0.3641396 2.351337 0.2304436





wind <- 600
p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            both_wing_index = 100*sum(min_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]>(10*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     )) %>% 
  ggplot(aes(x=genotype,y=both_wing_index)) +
    geom_boxplot()
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            both_wing_index = 100*sum(min_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]>(20*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     )) %>%
  ggplot(aes(x=genotype,y=both_wing_index)) +
    geom_boxplot()
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            both_wing_index = 100*sum(min_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]>(30*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     )) %>%
  ggplot(aes(x=genotype,y=both_wing_index)) +
    geom_boxplot()
p4 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            both_wing_index = 100*sum(min_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]>(40*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     )) %>%
  ggplot(aes(x=genotype,y=both_wing_index)) +
    geom_boxplot()
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c(">10deg",">20deg",">30deg",">40deg"),
          hjust = -0.6,
          vjust = 2,
          ncol = 4,
          nrow = 1)





test_stat_tibble <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  #filter(genotype != "A") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            both_wing_index = 100*sum(min_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]>(15*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     ))
aov1 <- aov(both_wing_index~genotype, data = test_stat_tibble)
TukeyHSD(aov1)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = both_wing_index ~ genotype, data = test_stat_tibble)

$genotype
          diff       lwr       upr     p adj
B-A  1.3374241 -4.537783  7.212632 0.9338504
C-A  1.9198669 -3.167234  7.006968 0.7588352
D-A 10.3410421  5.217313 15.464771 0.0000040
C-B  0.5824427 -5.190223  6.355108 0.9935904
D-B  9.0036180  3.198649 14.808587 0.0005495
D-C  8.4211753  3.415359 13.426992 0.0001503





wind <- 600
p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            mean_max_wing = mean(max_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ])
            ) %>% 
  ggplot(aes(x=genotype,y=mean_max_wing)) +
    geom_boxplot() +
    ylim(0,1.5)
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            mean_left_wing = -mean(wing_l_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ],na.rm = TRUE)
            ) %>%
  ggplot(aes(x=genotype,y=mean_left_wing)) +
    geom_boxplot() +
    ylim(0,1.5)
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            mean_right_wing = mean(wing_r_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ],na.rm = TRUE)
            ) %>%
  ggplot(aes(x=genotype,y=mean_right_wing)) +
    geom_boxplot() +
    ylim(0,1.5)
p4 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            mean_min_wing = mean(min_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ])
            ) %>%
  ggplot(aes(x=genotype,y=mean_min_wing)) +
    geom_boxplot() +
    ylim(0,1.5)
ggarrange(plotlist = list(p1,p4,p2,p3),
          labels = c("max wing","min wings","left wing","right wing"),
          hjust = -0.6,
          vjust = 2,
          ncol = 4,
          nrow = 1)



all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            mean_min_wing = mean(min_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ])
            ) %>%
  ggplot(aes(x=genotype,y=mean_min_wing)) +
    geom_boxplot() +
    ylim(0,.5)



all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            min_wing_gt_15 = sum(mean(min_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ])>15*pi/180)
            ) %>% 
  summarise(tot_min_wing_gt_15 = sum(min_wing_gt_15>0,na.rm = TRUE),
            prop_min_wing_gt_15 = 100*sum(min_wing_gt_15>0,na.rm = TRUE)/length(min_wing_gt_15))
There were 24 warnings (use warnings() to see them)





p1 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "A") %>% 
  ggplot(aes(x=-wing_l_ang__rad, y=wing_l_len__px)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,40) + 
  scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
p2 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "B") %>% 
  ggplot(aes(x=-wing_l_ang__rad, y=wing_l_len__px)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,40) + 
  scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
p3 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "C") %>% 
  ggplot(aes(x=-wing_l_ang__rad, y=wing_l_len__px)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,40) + 
  scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
p4 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "D") %>% 
  ggplot(aes(x=-wing_l_ang__rad, y=wing_l_len__px)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,40) + 
  scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c("A","B","C","D"),
          #hjust = 1,
          ncol = 2,
          nrow = 2)





p1 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "A") %>% 
  ggplot(aes(x=wing_r_ang__rad, y=wing_r_len__px)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,40) + 
  scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
p2 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "B") %>% 
  ggplot(aes(x=wing_r_ang__rad, y=wing_r_len__px)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,40) + 
  scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
p3 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "C") %>% 
  ggplot(aes(x=wing_r_ang__rad, y=wing_r_len__px)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,40) + 
  scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
p4 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "D") %>% 
  ggplot(aes(x=wing_r_ang__rad, y=wing_r_len__px)) +
  geom_bin2d(bins = c(200,50)) +
  xlim(0,2*pi) +
  ylim(0,40) + 
  scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c("A","B","C","D"),
          #hjust = 1,
          ncol = 2,
          nrow = 2)





p1 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "A") %>% 
  ggplot() +
  geom_bin2d(aes(x=wing_r_ang__rad, y=wing_r_len__px), bins = c(200,50)) +
  geom_bin2d(aes(x=wing_l_ang__rad, y=wing_l_len__px), bins = c(200,50)) +
  xlim(-pi,pi) +
  ylim(0,60) + 
  scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
p2 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "B") %>% 
  ggplot() +
  geom_bin2d(aes(x=wing_r_ang__rad, y=wing_r_len__px), bins = c(200,50)) +
  geom_bin2d(aes(x=wing_l_ang__rad, y=wing_l_len__px), bins = c(200,50)) +
  xlim(-pi,pi) +
  ylim(0,60) + 
  scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
p3 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "C") %>% 
  ggplot() +
  geom_bin2d(aes(x=wing_r_ang__rad, y=wing_r_len__px), bins = c(200,50)) +
  geom_bin2d(aes(x=wing_l_ang__rad, y=wing_l_len__px), bins = c(200,50)) +
  xlim(-pi,pi) +
  ylim(0,60) + 
  scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
p4 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "D") %>% 
  ggplot() +
  geom_bin2d(aes(x=wing_r_ang__rad, y=wing_r_len__px), bins = c(200,50)) +
  geom_bin2d(aes(x=wing_l_ang__rad, y=wing_l_len__px), bins = c(200,50)) +
  xlim(-pi,pi) +
  ylim(0,60) + 
  scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c("A","B","C","D"),
          #hjust = 1,
          ncol = 2,
          nrow = 2)

p1 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad < (2*pi/3)) %>%
  filter(min_wing_ang__rad > (0)) %>%
  filter(wing_l_ang__rad > (-2*pi/3)) %>%
  filter(wing_r_ang__rad < (2*pi/3)) %>%
  filter(wing_l_ang__rad < (0)) %>%
  filter(wing_r_ang__rad > (0)) %>%
  filter(dist_to_wall__mm > 2) %>%
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "A") %>% 
  ggplot() +
  geom_bin2d(aes(x=wing_r_ang__rad, y=wing_r_len__px), bins = c(200,50)) +
  geom_bin2d(aes(x=wing_l_ang__rad, y=wing_l_len__px), bins = c(200,50)) +
  xlim(-pi,pi) +
  ylim(0,60) + 
  scale_fill_continuous(type = "viridis",limits = c(10,500),na.value = "white") +
  theme_void() +
  coord_polar()
p2 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad < (2*pi/3)) %>%
  filter(min_wing_ang__rad > (0)) %>%
  filter(wing_l_ang__rad > (-2*pi/3)) %>%
  filter(wing_r_ang__rad < (2*pi/3)) %>%
  filter(wing_l_ang__rad < (0)) %>%
  filter(wing_r_ang__rad > (0)) %>%
  filter(dist_to_wall__mm > 2) %>%
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "B") %>% 
  ggplot() +
  geom_bin2d(aes(x=wing_r_ang__rad, y=wing_r_len__px), bins = c(200,50)) +
  geom_bin2d(aes(x=wing_l_ang__rad, y=wing_l_len__px), bins = c(200,50)) +
  xlim(-pi,pi) +
  ylim(0,60) + 
  scale_fill_continuous(type = "viridis",limits = c(10,500),na.value = "white") +
  theme_void() +
  coord_polar()
p3 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad < (2*pi/3)) %>%
  filter(min_wing_ang__rad > (0)) %>%
  filter(wing_l_ang__rad > (-2*pi/3)) %>%
  filter(wing_r_ang__rad < (2*pi/3)) %>%
  filter(wing_l_ang__rad < (0)) %>%
  filter(wing_r_ang__rad > (0)) %>%
  filter(dist_to_wall__mm > 2) %>%
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "C") %>% 
  ggplot() +
  geom_bin2d(aes(x=wing_r_ang__rad, y=wing_r_len__px), bins = c(200,50)) +
  geom_bin2d(aes(x=wing_l_ang__rad, y=wing_l_len__px), bins = c(200,50)) +
  xlim(-pi,pi) +
  ylim(0,60) + 
  scale_fill_continuous(type = "viridis",limits = c(10,500),na.value = "white") +
  theme_void() +
  coord_polar()
p4 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad < (2*pi/3)) %>%
  filter(min_wing_ang__rad > (0)) %>%
  filter(wing_l_ang__rad > (-2*pi/3)) %>%
  filter(wing_r_ang__rad < (2*pi/3)) %>%
  filter(wing_l_ang__rad < (0)) %>%
  filter(wing_r_ang__rad > (0)) %>%
  filter(dist_to_wall__mm > 2) %>%
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "D") %>% 
  ggplot() +
  geom_bin2d(aes(x=wing_r_ang__rad, y=wing_r_len__px), bins = c(200,50)) +
  geom_bin2d(aes(x=wing_l_ang__rad, y=wing_l_len__px), bins = c(200,50)) +
  xlim(-pi,pi) +
  ylim(0,60) + 
  scale_fill_continuous(type = "viridis",limits = c(10,500),na.value = "white") +
  theme_void() +
  coord_polar()
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c("A","B","C","D"),
          #hjust = 1,
          ncol = 2,
          nrow = 2)





p1 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "A") %>% 
  ggplot() +
  stat_density_2d(aes(x=wing_r_ang__rad, y=wing_r_len__px,fill = ..level..), geom = "polygon") +
  stat_density_2d(aes(x=wing_l_ang__rad, y=wing_l_len__px,fill = ..level..), geom = "polygon") +
  xlim(-pi,pi) +
  ylim(0,60) + 
  #scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
p2 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "B") %>% 
  ggplot() +
  stat_density_2d(aes(x=wing_r_ang__rad, y=wing_r_len__px,fill = ..level..), geom = "polygon") +
  stat_density_2d(aes(x=wing_l_ang__rad, y=wing_l_len__px,fill = ..level..), geom = "polygon") +
  xlim(-pi,pi) +
  ylim(0,60) + 
  #scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
p3 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "C") %>% 
  ggplot() +
  stat_density_2d(aes(x=wing_r_ang__rad, y=wing_r_len__px,fill = ..level..), geom = "polygon") +
  stat_density_2d(aes(x=wing_l_ang__rad, y=wing_l_len__px,fill = ..level..), geom = "polygon") +
  xlim(-pi,pi) +
  ylim(0,60) + 
  #scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
p4 <- all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(min_wing_ang__rad > (15*pi/180)) %>%
  filter(genotype == "D") %>% 
  ggplot() +
  stat_density_2d(aes(x=wing_r_ang__rad, y=wing_r_len__px,fill = ..level..), geom = "polygon") +
  stat_density_2d(aes(x=wing_l_ang__rad, y=wing_l_len__px,fill = ..level..), geom = "polygon") +
  xlim(-pi,pi) +
  ylim(0,60) + 
  #scale_fill_continuous(type = "viridis",limits = c(0,1000),na.value = "white") +
  theme_void() +
  coord_polar()
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c("A","B","C","D"),
          #hjust = 1,
          ncol = 2,
          nrow = 2)





all_rawdata %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(dist_to_other__mm < 10) %>% 
  filter(max_wing_ang__rad > (25*pi/180)) %>%
  #filter(genotype == "D") %>% 
  ggplot(aes(x=genotype, y=wing_l_len__px))+
  geom_boxplot()







Facing angle at start vs end of wing bout



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) %>%
  slice(which.max(SmoothedCourtship):which.max(SmoothedCopulation)) %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=-wing_l_ang__rad, colour = "#F8766D")) +
    geom_point(aes(y=wing_r_ang__rad, colour = "#00BFC4")) +
    geom_point(aes(y=c(ifelse(max_wing_ang__rad>=(25*pi/180),1.6,-1)))) +
    geom_point(aes(y=c(ifelse(WingGesture==1,WingGesture+0.8,WingGesture-1)))) +
    #geom_point(aes(y=c(ifelse(WingGesture==1,WingGesture+0.6,WingGesture-1)))) +
  ylim(0,2)



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_6") %>% 
  filter(Id == 7) %>%
  slice(which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                             ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)),
                                                    which.max(SmoothedCopulation),
                                                    min((which.max(SmoothedCourtship)+(25*600)),max(Frame))
                                                    ),
                                              min((which.max(SmoothedCourtship)+(25*600)),max(Frame))
                                              )) %>%
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=-wing_l_ang__rad, colour = "#F8766D")) +
    geom_point(aes(y=wing_r_ang__rad, colour = "#00BFC4")) +
    geom_point(aes(y=c(ifelse(max_wing_ang__rad>=(35*pi/180),1.6,-1)))) +
    geom_point(aes(y=c(ifelse(WingGesture==1,WingGesture+0.8,WingGesture-1)))) +
    #geom_point(aes(y=c(ifelse(WingGesture==1,WingGesture+0.6,WingGesture-1)))) +
  ylim(0,2)



all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 5) %>%
  slice(which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                             ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)),
                                                    which.max(SmoothedCopulation),
                                                    min((which.max(SmoothedCourtship)+(25*600)),max(Frame))
                                                    ),
                                              min((which.max(SmoothedCourtship)+(25*600)),max(Frame))
                                              )) %>%
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=-wing_l_ang__rad, colour = "#F8766D")) +
    geom_point(aes(y=wing_r_ang__rad, colour = "#00BFC4")) +
    geom_point(aes(y=c(ifelse(max_wing_ang__rad>=(35*pi/180),1.6,-1)))) +
    geom_point(aes(y=c(ifelse(WingGesture==1,WingGesture+0.8,WingGesture-1)))) +
    #geom_point(aes(y=c(ifelse(WingGesture==1,WingGesture+0.6,WingGesture-1)))) +
  ylim(0,2)





Facing angle at start and end of each bout

temp <- all_rawdata %>% 
  filter(genotype!="CS female") %>% 
  filter(dist_to_other__mm > 2)
  
uniq_fly <- unique(temp$unique_fly)
facing_start_and_end_wing <- tibble()
for (fly in uniq_fly) {
  temp2 <- filter(temp, unique_fly == fly)
  bouts <- rle(temp2$WingGesture)
  
  starts <- as.numeric()
  for (i in seq(1,length(which(bouts$values==1)),1)) {
    starts[i] = sum(bouts$lengths[1:(i*2)-1])+1
  }
  ends <- as.numeric()
  for (i in seq(1,length(which(bouts$values==1)),1)) {
    ends[i] = sum(bouts$lengths[1:(i*2)])
  }
  genotype = rep(unique(temp2$genotype),length(which(bouts$values==1)))
  uni_id = rep(unique(temp2$unique_fly),length(which(bouts$values==1)))
  
  temp_tibble <- tibble(unique_fly = uni_id,
                        genotype = genotype,
                        facing_at_start = temp2$facing_angle__rad[starts],
                        facing_at_end = temp2$facing_angle__rad[ends]
                        )
  facing_start_and_end_wing <- bind_rows(facing_start_and_end_wing,temp_tibble)
}
facing_start_and_end_wing



p1 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_start)) +
  geom_boxplot()
p2 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_end)) +
  geom_boxplot()
p3 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_start/facing_at_end)) +
  geom_boxplot() +
  ylim(0,2)
ggarrange(plotlist = list(p1,p2,p3),
          labels = c("Facing Angle at Start","Facing Angle at End","Ratio start:end"),
          hjust = -0.2,
          vjust = 1.6,
          ncol = 3,
          nrow = 1)



p1 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_start-facing_at_end)) +
  geom_boxplot()+
  ylim(-0.5,0.5)
p2 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_end-facing_at_start)) +
  geom_boxplot()+
  ylim(-0.5,0.5)
p3 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_start/facing_at_end)) +
  geom_boxplot() +
  ylim(0,2)
ggarrange(plotlist = list(p1,p2,p3),
          labels = c("Start-End","End-Start","Ratio start:end"),
          hjust = -0.2,
          vjust = 1.6,
          ncol = 3,
          nrow = 1)



p1 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_start)) +
  geom_violin()
p2 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_end)) +
  geom_violin()
ggarrange(plotlist = list(p1,p2),
          labels = c("Facing Angle at Start","Facing Angle at End"),
          #hjust = -0.6,
          #vjust = 2,
          ncol = 2,
          nrow = 1)







Mean facing angle at start and end of bout

temp <- all_rawdata %>% 
  filter(genotype!="CS female") %>% 
  filter(dist_to_other__mm > 2)
  
uniq_fly <- unique(temp$unique_fly)
facing_start_and_end_wing <- tibble()
for (fly in uniq_fly) {
  temp2 <- filter(temp, unique_fly == fly)
  bouts <- rle(temp2$WingGesture)
  
  starts <- as.numeric()
  for (i in seq(1,length(which(bouts$values==1)),1)) {
    starts[i] = sum(bouts$lengths[1:(i*2)-1])+1
  }
  ends <- as.numeric()
  for (i in seq(1,length(which(bouts$values==1)),1)) {
    ends[i] = sum(bouts$lengths[1:(i*2)])
  }
  genotype = unique(temp2$genotype)
  uni_id = unique(temp2$unique_fly)
  
  temp_tibble <- tibble(unique_fly = uni_id,
                        genotype = genotype,
                        facing_at_start = mean(temp2$facing_angle__rad[starts]),
                        facing_at_end = mean(temp2$facing_angle__rad[ends])
                        )
  facing_start_and_end_wing <- bind_rows(facing_start_and_end_wing,temp_tibble)
}
facing_start_and_end_wing



p1 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_start)) +
  geom_boxplot() +
  ylim(0,1)
p2 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_end)) +
  geom_boxplot() +
  ylim(0,1)
ggarrange(plotlist = list(p1,p2),
          labels = c("mean Facing Angle at Start","mean Facing Angle at End"),
          #hjust = -0.6,
          #vjust = 2,
          ncol = 2,
          nrow = 1)





Median facing angle at start and end of bout (using WingGesture)

temp <- all_rawdata %>% 
  filter(genotype!="CS female") %>% 
  filter(dist_to_other__mm > 2)
  
uniq_fly <- unique(temp$unique_fly)
facing_start_and_end_wing <- tibble()
for (fly in uniq_fly) {
  temp2 <- filter(temp, unique_fly == fly)
  bouts <- rle(temp2$WingGesture)
  
  starts <- as.numeric()
  for (i in seq(1,length(which(bouts$values==1)),1)) {
    starts[i] = sum(bouts$lengths[1:(i*2)-1])+1
  }
  ends <- as.numeric()
  for (i in seq(1,length(which(bouts$values==1)),1)) {
    ends[i] = sum(bouts$lengths[1:(i*2)])
  }
  genotype = unique(temp2$genotype)
  uni_id = unique(temp2$unique_fly)
  
  temp_tibble <- tibble(unique_fly = uni_id,
                        genotype = genotype,
                        facing_at_start = median(temp2$facing_angle__rad[starts]),
                        facing_at_end = median(temp2$facing_angle__rad[ends])
                        )
  facing_start_and_end_wing <- bind_rows(facing_start_and_end_wing,temp_tibble)
}
facing_start_and_end_wing



p1 <- all_rawdata %>% 
  filter(genotype!="CS female") %>% 
  group_by(unique_fly) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(WingGesture==1) %>% 
  summarise(genotype = unique(genotype),
            median_facing = median(facing_angle__rad)) %>% 
  ggplot(aes(x=genotype,y=median_facing)) +
    geom_boxplot() +
    ylim(0,0.5)
p2 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_start)) +
  geom_boxplot() +
  ylim(0,0.5)
p3 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_end)) +
  geom_boxplot() +
  ylim(0,0.5)
p4 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_start/facing_at_end)) +
  geom_boxplot() #+
  #ylim(0,0.5)
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c("median Facing angle throughout","median at Start of each bout","median at End of each bout","ratio start:end"),
          hjust = -0.2,
          vjust = 2,
          ncol = 4,
          nrow = 1)





Median facing angle at start and end of bout (using >35deg)

temp <- all_rawdata %>% 
  filter(genotype!="CS female") %>% 
  filter(dist_to_other__mm > 2)
  
uniq_fly <- unique(temp$unique_fly)
facing_start_and_end_wing <- tibble()
for (fly in uniq_fly) {
  temp2 <- filter(temp, unique_fly == fly)
  #bouts <- rle(temp2$WingGesture)
  temp2$bin_max_wing <- ifelse(temp2$max_wing_ang__rad >= (35*pi/180),1,0)
  temp2$bin_max_wing <- temp2$bin_max_wing %>% replace_na(0)
  bouts <- rle(temp2$bin_max_wing)
  starts <- as.numeric()
  for (i in seq(1,length(which(bouts$values==1)),1)) {
    starts[i] = sum(bouts$lengths[1:(i*2)-1])+1
  }
  ends <- as.numeric()
  for (i in seq(1,length(which(bouts$values==1)),1)) {
    ends[i] = sum(bouts$lengths[1:(i*2)])
  }
  genotype = unique(temp2$genotype)
  uni_id = unique(temp2$unique_fly)
  
  temp_tibble <- tibble(unique_fly = uni_id,
                        genotype = genotype,
                        facing_at_start = median(temp2$facing_angle__rad[starts]),
                        facing_at_end = median(temp2$facing_angle__rad[ends])
                        )
  facing_start_and_end_wing <- bind_rows(facing_start_and_end_wing,temp_tibble)
}
facing_start_and_end_wing



p1 <- all_rawdata %>% 
  filter(genotype!="CS female") %>% 
  group_by(unique_fly) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  summarise(genotype = unique(genotype),
            median_facing = median(facing_angle__rad)) %>% 
  ggplot(aes(x=genotype,y=median_facing)) +
    geom_boxplot() +
    ylim(0,0.5)
p2 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_start)) +
  geom_boxplot() +
  ylim(0,0.5)
p3 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_end)) +
  geom_boxplot() +
  ylim(0,0.5)
p4 <- ggplot(facing_start_and_end_wing, aes(x=genotype,y=facing_at_start/facing_at_end)) +
  geom_boxplot() #+
  #ylim(0,0.5)
ggarrange(plotlist = list(p1,p2,p3,p4),
          labels = c("median Facing angle throughout","median at Start of each bout","median at End of each bout","ratio start:end"),
          hjust = -0.2,
          vjust = 2,
          ncol = 4,
          nrow = 1)





Facing angles with wing extended using WingGesture

p1 <- all_rawdata %>% 
  filter(genotype!="CS female") %>% 
  group_by(unique_fly) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(WingGesture==1) %>% 
  ggplot(aes(x=genotype,y=facing_angle__rad)) +
    geom_boxplot() +
    ylim(0,1)
p2 <- all_rawdata %>% 
  filter(genotype!="CS female") %>% 
  group_by(unique_fly) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(WingGesture==1) %>% 
  summarise(genotype = unique(genotype),
            median_facing = median(facing_angle__rad)) %>% 
  ggplot(aes(x=genotype,y=median_facing)) +
    geom_boxplot() +
    ylim(0,1)
p3 <- all_rawdata %>% 
  filter(genotype!="CS female") %>% 
  group_by(unique_fly) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(WingGesture==1) %>% 
  summarise(genotype = unique(genotype),
            mean_facing = mean(facing_angle__rad)) %>% 
  ggplot(aes(x=genotype,y=mean_facing)) +
    geom_boxplot() +
    ylim(0,1)
ggarrange(plotlist = list(p1,p2,p3),
          labels = c("Facing Angle","median Facing Angle","mean Facing Angle"),
          #hjust = -0.6,
          #vjust = 2,
          ncol = 3,
          nrow = 1)





Facing angles with wing extended using max_wing>35

p1 <- all_rawdata %>% 
  filter(genotype!="CS female") %>% 
  group_by(unique_fly) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  ggplot(aes(x=genotype,y=facing_angle__rad)) +
    geom_boxplot() +
    ylim(0,1)
p2 <- all_rawdata %>% 
  filter(genotype!="CS female") %>% 
  group_by(unique_fly) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  summarise(genotype = unique(genotype),
            median_facing = median(facing_angle__rad)) %>% 
  ggplot(aes(x=genotype,y=median_facing)) +
    geom_boxplot() +
    ylim(0,1)
p3 <- all_rawdata %>% 
  filter(genotype!="CS female") %>% 
  group_by(unique_fly) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  summarise(genotype = unique(genotype),
            mean_facing = mean(facing_angle__rad)) %>% 
  ggplot(aes(x=genotype,y=mean_facing)) +
    geom_boxplot() +
    ylim(0,1)
ggarrange(plotlist = list(p1,p2,p3),
          labels = c("Facing Angle","median Facing Angle","mean Facing Angle"),
          #hjust = -0.6,
          #vjust = 2,
          ncol = 3,
          nrow = 1)



test_stat_tibble0 <- all_rawdata %>% 
  filter(genotype!="CS female") %>% 
  group_by(unique_fly) %>% 
  filter(dist_to_other__mm > 2) %>% 
  filter(max_wing_ang__rad > (35*pi/180)) %>%
  summarise(genotype = unique(genotype),
            facing = median(facing_angle__rad)) 
aov0 <- aov(facing~genotype,data = test_stat_tibble0)
#summary(aov0)
TukeyHSD(aov0)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = facing ~ genotype, data = test_stat_tibble0)

$genotype
            diff        lwr       upr     p adj
B-A -0.064278836 -0.2941883 0.1656306 0.8852971
C-A -0.017473865 -0.2165430 0.1815953 0.9957523
D-A -0.012774271 -0.2132767 0.1877282 0.9983603
C-B  0.046804972 -0.1790918 0.2727017 0.9489797
D-B  0.051504566 -0.1756563 0.2786654 0.9345696
D-C  0.004699594 -0.1911887 0.2005879 0.9999116











test <- all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) 
temp2 <- test
#bouts <- rle(temp2$WingGesture)
temp2$bin_max_wing <- ifelse(temp2$max_wing_ang__rad > (35*pi/180),1,0)
temp2$bin_max_wing <- temp2$bin_max_wing %>% replace_na(0)
bouts <- rle(temp2$bin_max_wing)
starts <- as.numeric()
for (i in seq(1,length(which(bouts$values==1)),1)) {
  starts[i] = sum(bouts$lengths[1:(i*2)-1])+1
}
ends <- as.numeric()
for (i in seq(1,length(which(bouts$values==1)),1)) {
  ends[i] = sum(bouts$lengths[1:(i*2)])
}
genotype = rep(unique(temp2$genotype),length(which(bouts$values==1)))
uni_id = rep(unique(temp2$unique_fly),length(which(bouts$values==1)))
temp_tibble <- tibble(unique_fly = uni_id,
                      genotype = genotype,
                      facing_at_start = temp2$facing_angle__rad[starts],
                      facing_at_end = temp2$facing_angle__rad[ends]
                      )
temp_tibble
starts = for (i in seq(1,length(which(bouts$values==1)),1)) {
                                           starts[i] = sum(bouts$lengths[1:(i*2)-1])+1
                                         }
starts
NULL
test$bin_max_wing <- ifelse(test$max_wing_ang__rad > (35*pi/180),1,0)
test$bin_max_wing <- test$bin_max_wing %>% replace_na(0)
#test$bin_max_wing
bouts <- rle(test$bin_max_wing)
bouts
Run Length Encoding
  lengths: int [1:393] 675 3 2 14 2 22 212 15 15 2 ...
  values : num [1:393] 0 1 0 1 0 1 0 1 0 1 ...
bouts <- rle(test$WingGesture)
bouts
Run Length Encoding
  lengths: int [1:1361] 666 5 3 45 198 1 2 5 4 17 ...
  values : num [1:1361] 0 1 0 1 0 1 0 1 0 1 ...
test <- all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) 
test$bin_max_wing <- ifelse(test$max_wing_ang__rad > (35*pi/180),1,0)
test$bin_max_wing <- test$bin_max_wing %>% replace_na(0)
test %>% 
  slice(which.max(SmoothedCourtship):which.max(SmoothedCopulation)) %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=-wing_l_ang__rad, colour = "#F8766D")) +
    geom_point(aes(y=wing_r_ang__rad, colour = "#00BFC4")) +
    geom_point(aes(y=c(ifelse(bin_max_wing==1,1.6,-1)))) +
    geom_point(aes(y=c(ifelse(max_wing_ang__rad>=(35*pi/180),1.8,-1)))) +
    geom_point(aes(y=c(ifelse(WingGesture==1,WingGesture+1,WingGesture-1)))) +
    ylim(0,2.2)

sum(test$bin_max_wing[which.max(test$SmoothedCourtship):which.max(test$SmoothedCopulation)]==test$WingGesture[which.max(test$SmoothedCourtship):which.max(test$SmoothedCopulation)])
[1] 1230
sum(test$bin_max_wing[which.max(test$SmoothedCourtship):which.max(test$SmoothedCopulation)]!=test$WingGesture[which.max(test$SmoothedCourtship):which.max(test$SmoothedCopulation)])
[1] 35
test <- all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_123_3") %>% 
  filter(Id == 1) 
test$bin_max_wing <- ifelse(test$max_wing_ang__rad > (35*pi/180),1,0)
test$bin_max_wing <- test$bin_max_wing %>% replace_na(0)
test %>% 
  #slice(which.max(SmoothedCourtship):which.max(SmoothedCopulation)) %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=-wing_l_ang__rad, colour = "#F8766D")) +
    geom_point(aes(y=wing_r_ang__rad, colour = "#00BFC4")) +
    geom_point(aes(y=c(ifelse(bin_max_wing==1,1.6,-1)))) +
    geom_point(aes(y=c(ifelse(max_wing_ang__rad>=(35*pi/180),1.8,-1)))) +
    geom_point(aes(y=c(ifelse(WingGesture==1,WingGesture+1,WingGesture-1)))) +
    ylim(0,2.2)

gg_color_hue(4)
[1] "#F8766D" "#7CAE00" "#00BFC4" "#C77CFF"
test <- all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_123_3") %>% 
  filter(Id == 1) %>% 
  filter(dist_to_other__mm > 2)
test$bin_max_wing <- ifelse(test$max_wing_ang__rad >= (35*pi/180),1,0)
test$bin_max_wing <- test$bin_max_wing %>% replace_na(0)
test %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=dist_to_other__mm, colour = "#F8766D")) +
    geom_point(aes(y=SmoothedDistToOther-1, colour = "#7CAE00")) +
    geom_point(aes(y=(SmoothedCopulation-2), colour= "#00BFC4")) +
    geom_point(aes(y=c(ifelse(bin_max_wing==1,-3,-10)))) +
    geom_point(aes(y=c(ifelse(max_wing_ang__rad>=(35*pi/180),-4,-10)))) +
    geom_point(aes(y=c(ifelse(WingGesture==1,-6,-10)))) +
    geom_point(aes(y=c(ifelse(SmoothedCourtship==1,20,-10)))) +
    ylim(-6,20)

max(test$Frame)
[1] 5974
temp2 <- all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_123_3") %>% 
  filter(Id == 1) %>% 
  filter(dist_to_other__mm > 2)
#bouts <- rle(temp2$WingGesture)
temp2$bin_max_wing <- ifelse(temp2$max_wing_ang__rad >= (35*pi/180),1,0)
temp2$bin_max_wing <- temp2$bin_max_wing %>% replace_na(0)
bouts <- rle(test$bin_max_wing)
starts <- as.numeric()
for (i in seq(1,length(which(bouts$values==1)),1)) {
  starts[i] = sum(bouts$lengths[1:(i*2)-1])+1
}
ends <- as.numeric()
for (i in seq(1,length(which(bouts$values==1)),1)) {
  ends[i] = sum(bouts$lengths[1:(i*2)])
}
genotype = unique(temp2$genotype)
uni_id = unique(temp2$unique_fly)
temp_tibble <- tibble(unique_fly = uni_id,
                      genotype = genotype,
                      facing_at_start = median(temp2$facing_angle__rad[starts]),
                      facing_at_end = median(temp2$facing_angle__rad[ends])
                      )
temp_tibble
bouts <- rle(test$bin_max_wing)
bouts
Run Length Encoding
  lengths: int [1:198] 631 3 57 5 363 34 357 1 23 1 ...
  values : num [1:198] 0 1 0 1 0 1 0 1 0 1 ...
all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_123_3") %>% 
  filter(Id == 21) %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=SmoothedCourtship, colour = "#F8766D")) +
    geom_point(aes(y=(SmoothedCopulation+0.1), colour= "#00BFC4")) #+

    #xlim(2000,3000)
all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) %>%
  #slice(which.max(SmoothedCourtship):which.max(SmoothedCopulation)) %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=wing_l_ang__rad, colour = "#F8766D")) +
    geom_point(aes(y=wing_r_ang__rad, colour = "#00BFC4"))

NA
all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) %>%
  slice(which.max(SmoothedCourtship):which.max(SmoothedCopulation)) %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=-wing_l_ang__rad, colour = "#F8766D")) +
    geom_point(aes(y=wing_r_ang__rad, colour = "#00BFC4")) +
    geom_point(aes(y=c(ifelse(WingGesture==1,WingGesture+0.6,WingGesture-0.2))))

all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) %>%
  slice(which.max(SmoothedCourtship):which.max(SmoothedCopulation)) %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=-wing_l_ang__rad, colour = "#F8766D")) +
    geom_point(aes(y=wing_r_ang__rad, colour = "#00BFC4")) +
    geom_point(aes(y=c(ifelse(WingGesture==1,WingGesture+0.6,NA))))

all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) %>% 
  ggplot(aes(x=Frame,y=dist_to_other__mm)) +
    geom_point(aes(colour=c(ifelse(SmoothedDistToOther>0.5,"not copulating","copulating"))))+
    geom_point(aes(y=c(ifelse(SmoothedCopulation==1,SmoothedCopulation+6,NA))))

all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=SmoothedDistToOther, colour = "#F8766D")) +
    geom_point(aes(y=(SmoothedCopulation+0.1), colour= "#00BFC4")) +
    xlim(2000,3000)

all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=SmoothedCourtship, colour = "#F8766D")) +
    geom_point(aes(y=(SmoothedCopulation+0.1), colour= "#00BFC4")) #+

    #xlim(2000,3000)

Trying to make functions for courtship window and calculate indices… they aren’t working right, and seem to be ignoring the grouping of the tibble and returning the same value for every individual…

If i have to for loop over the groups of a tibble, the below line might be usefull. dim(unique(all_rawdata[all_rawdata %>% group_by(genotype) %>% group_vars()]))[1]

courtship_window <- function(input,wind=600,...){
  temp_tibble <- summarise(input, start_of_courtship = which.max(SmoothedCourtship),
                                  end_of_courtship = ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                             ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                    which.max(SmoothedCopulation), 
                                                                    min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                    ),
                                                              min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                              )
                        )
  return(temp_tibble$start_of_courtship:temp_tibble$end_of_courtship)
  #return(c(temp_tibble$start_of_courtship,temp_tibble$end_of_courtship))
  #return(temp_tibble)
}
courtship_window <- function(input,wind=600,...){
  temp_tibble <- summarise(input, start_of_courtship = which.max(SmoothedCourtship),
                                  end_of_courtship = ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                             ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                    which.max(SmoothedCopulation), 
                                                                    min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                    ),
                                                              min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                              )
                        )
  #return(temp_tibble$start_of_courtship:temp_tibble$end_of_courtship)
  return(c(temp_tibble$start_of_courtship,temp_tibble$end_of_courtship))
  #return(temp_tibble)
}
courtship_window(test, wind = 600)
temp <- all_rawdata %>% 
  filter(genotype!="CS female")

uniq_fly <- unique(temp$unique_fly)
courting_frames <- tibble()
for (fly in uniq_fly) {
  temp2 <- temp %>% filter(unique_fly == fly) 
  temp2 <- slice(temp2, which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                             ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*wind)), 
                                                                    which.max(SmoothedCopulation), 
                                                                    min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                    ),
                                                              min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                              ))
  courting_frames <- bind_rows(courting_frames,temp2)
}
courting_frames
test <- all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_123_3") %>% 
  filter(Id == 1) %>% 
  filter(dist_to_other__mm > 2)

#test$bin_max_wing <- ifelse(test$max_wing_ang__rad >= (35*pi/180),1,0)
#test$bin_max_wing <- test$bin_max_wing %>% replace_na(0)

test %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=dist_to_other__mm, colour = "#F8766D")) +
    geom_point(aes(y=SmoothedDistToOther-1, colour = "#7CAE00")) +
    geom_point(aes(y=(SmoothedCopulation-2), colour= "#00BFC4")) +

    #geom_point(aes(y=c(ifelse(bin_max_wing==1,-3,-10)))) +
    geom_point(aes(y=c(ifelse(max_wing_ang__rad>=(35*pi/180),-4,-10)))) +
    geom_point(aes(y=c(ifelse(WingGesture==1,-6,-10)))) +
    geom_point(aes(y=c(ifelse(SmoothedCourtship==1,20,-10)))) +
    ylim(-6,20)
test <- courting_frames %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_123_3") %>% 
  filter(Id == 1) #%>% 
  #filter(dist_to_other__mm > 2)

#test$bin_max_wing <- ifelse(test$max_wing_ang__rad >= (35*pi/180),1,0)
#test$bin_max_wing <- test$bin_max_wing %>% replace_na(0)

test %>% 
  ggplot(aes(x=Frame)) +
    geom_point(aes(y=dist_to_other__mm, colour = "#F8766D")) +
    geom_point(aes(y=ifelse(SmoothedDistToOther==1,1,-10), colour = "#7CAE00")) +
    geom_point(aes(y=ifelse(SmoothedCopulation==0,-2,-10), colour= "#00BFC4")) +
    geom_point(aes(y=ifelse(Copulation==0,-1,-10), colour= "#00BFC4")) +

    #geom_point(aes(y=c(ifelse(bin_max_wing==1,-3,-10)))) +
    geom_point(aes(y=c(ifelse(max_wing_ang__rad>=(35*pi/180),-4,-10)))) +
    geom_point(aes(y=c(ifelse(WingGesture==1,-6,-10)))) +
    geom_point(aes(y=c(ifelse(SmoothedCourtship==1,20,-10)))) +
    geom_point(aes(y=c(ifelse(Courtship==1,18,-10)))) +
    ylim(-6,20)
calculate_indices <- function(input = .,feature,jaaba=TRUE,thresh=NULL,wind=600){
  if (feature %in% names(input)) {
    var_ind = paste0(feature,"_index")
    if (jaaba) {
      temp_tibble <- summarise(input, genotype = unique(genotype), 
                                      !!var_ind := 100*sum(input[[feature]][which.max(input[["SmoothedCourtship"]]):ifelse(which.max(input[["SmoothedCopulation"]]) > which.max(input[["SmoothedCourtship"]]),
                                                       ifelse(which.max(input[["SmoothedCopulation"]]) <= (which.max(input[["SmoothedCourtship"]])+(25*wind)), 
                                                              which.max(input[["SmoothedCopulation"]]), 
                                                              min((which.max(input[["SmoothedCourtship"]])+(25*wind)),max(input[["Frame"]]))
                                                              ),
                                                        min((which.max(input[["SmoothedCourtship"]])+(25*wind)),max(input[["Frame"]]))
                                                        )])/
                                                    length(input[["Frame"]][which.max(input[["SmoothedCourtship"]]):ifelse(which.max(input[["SmoothedCopulation"]]) > which.max(input[["SmoothedCourtship"]]),
                                                       ifelse(which.max(input[["SmoothedCopulation"]]) <= (which.max(input[["SmoothedCourtship"]])+(25*wind)), 
                                                              which.max(input[["SmoothedCopulation"]]), 
                                                              min((which.max(input[["SmoothedCourtship"]])+(25*wind)),max(input[["Frame"]]))
                                                              ),
                                                        min((which.max(input[["SmoothedCourtship"]])+(25*wind)),max(input[["Frame"]]))
                                                        )])
                )
    } else {
      temp_tibble <- summarise(input, genotype = unique(genotype), 
                                      !!var_ind := 100*sum(input[[feature]][which.max(input[["SmoothedCourtship"]]):ifelse(which.max(input[["SmoothedCopulation"]]) > which.max(input[["SmoothedCourtship"]]),
                                                       ifelse(which.max(input[["SmoothedCopulation"]]) <= (which.max(input[["SmoothedCourtship"]])+(25*wind)), 
                                                              which.max(input[["SmoothedCopulation"]]), 
                                                              min((which.max(input[["SmoothedCourtship"]])+(25*wind)),max(input[["Frame"]]))
                                                              ),
                                                        min((which.max(input[["SmoothedCourtship"]])+(25*wind)),max(input[["Frame"]]))
                                                        )]>thresh,na.rm = TRUE)/
                                                    length(input[["Frame"]][which.max(input[["SmoothedCourtship"]]):ifelse(which.max(input[["SmoothedCopulation"]]) > which.max(input[["SmoothedCourtship"]]),
                                                       ifelse(which.max(input[["SmoothedCopulation"]]) <= (which.max(input[["SmoothedCourtship"]])+(25*wind)), 
                                                              which.max(input[["SmoothedCopulation"]]), 
                                                              min((which.max(input[["SmoothedCourtship"]])+(25*wind)),max(input[["Frame"]]))
                                                              ),
                                                        min((which.max(input[["SmoothedCourtship"]])+(25*wind)),max(input[["Frame"]]))
                                                        )])
                )
    }
    return(temp_tibble)
  } else {
    message(paste0(feature, " does not exist in table"))
  }
} 
calculate_indices <- function(input,feature,jaaba=TRUE,thresh=NULL){
  if (feature %in% names(input)) {
    var_ind = paste0(feature,"_index")
    if (jaaba) {
      temp_tibble <- summarise(input, genotype = unique(genotype), 
                                      !!var_ind := 100*sum(input[[feature]][courtship_window(input)])/
                                                    length(input[["Frame"]][courtship_window(input)])
                )
    } else {
      temp_tibble <- summarise(input, genotype = unique(genotype), 
                                      !!var_ind := 100*sum(input[[feature]][courtship_window(input)]>thresh,na.rm = TRUE)/
                                                    length(input[["Frame"]][courtship_window(input)])
                )
    }
    return(temp_tibble)
  } else {
    message(paste0(feature, " does not exist in table"))
  }
} 
p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(unique_fly) %>% 
  calculate_indices(feature = "max_wing_ang__rad",jaaba = FALSE,thresh = (25*pi/180)) %>% 
  ggplot(aes(x=genotype,y=max_wing_ang__rad_index)) +
    geom_boxplot()
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(unique_fly) %>% 
  calculate_indices(feature = "wing_l_ang__rad",jaaba = FALSE,thresh = (25*pi/180)) %>% 
  ggplot(aes(x=genotype,y=wing_l_ang__rad_index)) +
    geom_boxplot()
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(unique_fly) %>% 
  calculate_indices(feature = "wing_r_ang__rad",jaaba = FALSE,thresh = (25*pi/180)) %>% 
  ggplot(aes(x=genotype,y=wing_r_ang__rad_index)) +
    geom_boxplot()
ggarrange(plotlist = list(p1,p2,p3),
          labels = c("wing index","left wing","right wing"),
          hjust = -0.6,
          vjust = 2,
          ncol = 3,
          nrow = 1)
p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            wing_index = 100*sum(max_wing_ang__rad[courtship_window(input)]>(40*pi/180),
                                 na.rm = TRUE)/
              length(Frame[courtship_window(input)]
                     )) %>% 
  ggplot(aes(x=genotype,y=wing_index)) +
    geom_boxplot()
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            left_wing_index = 100*sum(wing_l_ang__rad[courtship_window(input)]<(-40*pi/180),
                                 na.rm = TRUE)/
              length(Frame[courtship_window(input)]
                     )) %>%
  ggplot(aes(x=genotype,y=left_wing_index)) +
    geom_boxplot()
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            right_wing_index = 100*sum(wing_r_ang__rad[courtship_window(input)]>(40*pi/180),
                                 na.rm = TRUE)/
              length(Frame[courtship_window(input)]
                     )) %>%
  ggplot(aes(x=genotype,y=right_wing_index)) +
    geom_boxplot()
ggarrange(plotlist = list(p1,p2,p3),
          labels = c("wing index","left wing","right wing"),
          hjust = -0.6,
          vjust = 2,
          ncol = 3,
          nrow = 1)
p1 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            wing_index = 100*sum(max_wing_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]>(40*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     )) %>% 
  ggplot(aes(x=genotype,y=wing_index)) +
    geom_boxplot()
p2 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            left_wing_index = 100*sum(wing_l_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]<(-40*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     )) %>%
  ggplot(aes(x=genotype,y=left_wing_index)) +
    geom_boxplot()
p3 <- all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  summarise(genotype = unique(genotype),
            right_wing_index = 100*sum(wing_r_ang__rad[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]>(40*pi/180),
                                 na.rm = TRUE)/
              length(Frame[which.max(SmoothedCourtship):ifelse(which.max(SmoothedCopulation) > which.max(SmoothedCourtship),
                                                                                 ifelse(which.max(SmoothedCopulation) <= (which.max(SmoothedCourtship)+(25*600)), 
                                                                                        which.max(SmoothedCopulation), 
                                                                                        min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                        ),
                                                                                  min((which.max(SmoothedCourtship)+(25*wind)),max(Frame))
                                                                                  )
                                             ]
                     )) %>%
  ggplot(aes(x=genotype,y=right_wing_index)) +
    geom_boxplot()
ggarrange(plotlist = list(p1,p2,p3),
          labels = c("wing index","left wing","right wing"),
          hjust = -0.6,
          vjust = 2,
          ncol = 3,
          nrow = 1)
all_rawdata %>% 
  filter(genotype != "CS female") %>% 
  filter(genotype == "D") %>% 
  group_by(genotype) %>% 
  group_by(unique_fly) %>% 
  calculate_indices(feature = "max_wing_ang__rad",jaaba = FALSE,thresh = (25*pi/180))
test <- all_rawdata %>% 
  filter(FileName == "Megan-2019_03_06_Courtship-DsxVglutTNT_Male_1234_2") %>% 
  filter(Id == 36) 
calculate_indices(input = test,feature = "WingGesture",jaaba = TRUE)
calculate_indices(input = test,feature = "max_wing_ang__rad",jaaba = FALSE,thresh = (25*pi/180))
calculate_indices(input = test,feature = "max_wing_angle__rad",jaaba = FALSE,thresh = (25*pi/180))
LS0tCnRpdGxlOiAiKipNYWxlIGNvdXJ0c2hpcCBiZWhhdmlvdXIgLSBhRE4gPiBUTlQqKiIKYXV0aG9yOiAiQWFyb24gTS4gQWxsZW4iCmRhdGU6ICIyNCBGZWJydWFyeSAyMDIwIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgo8YnIvPgo8YnIvPgoKIyAqKlNldHVwKioKCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkoInRpZHl2ZXJzZSIpCmxpYnJhcnkoImdncHViciIpCmxpYnJhcnkoInpvbyIpCnNldHdkKCIvbW50L0xvY2FsRGF0YS9iZWhhdmlvdXIvYUROL2FETl9iZWhhdmlvdXIiKQpgYGAKCgo8YnIvPgo8YnIvPgoKCiMjIyBDb2xvdXJzIC4uLgogCmBgYHtyfQpnZ19jb2xvcl9odWUgPC0gZnVuY3Rpb24obikgewogIGh1ZXMgPSBzZXEoMTUsIDM3NSwgbGVuZ3RoID0gbiArIDEpCiAgaGNsKGggPSBodWVzLCBsID0gNjUsIGMgPSAxMDApWzE6bl0KfQpgYGAKCmBgYHtyfQpnZ19jb2xvcl9odWUoMikKYGBgCgoKCjxici8+Cjxici8+CgoKCmBgYHtyIG1lc3NhZ2U9RkFMU0V9Cmdlbm90eXBlcyA8LSByZWFkX3RzdigiLi4vMjAxOV8wM18wNl9Db3VydHNoaXAvZ2Vub3R5cGUudHN2Iixjb2xfbmFtZXMgPSBUUlVFKQpnZW5vdHlwZXMKYGBgCgoKCjxici8+Cjxici8+CgoKCgoKCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CiMgaW5kaWNlc19saXN0IDwtIGxpc3QuZmlsZXMoInJhdyBkYXRhLyIpICU+JSBzdHJfc3Vic2V0KCJfSW5kaWNlcy5jc3YiKQppbmRpY2VzX2xpc3QgPC0gbGlzdC5maWxlcygiLi4vMjAxOV8wM18wNl9Db3VydHNoaXAvIixyZWN1cnNpdmUgPSBUUlVFKSAlPiUgc3RyX3N1YnNldCgiX0luZGljZXMuY3N2IikgJT4lIHN0cl9zdWJzZXQoIk1hbGUiKQphbGxfaW5kaWNlcyA8LSB0aWJibGUoKQpmb3IgKGluZGljZXNfZmlsZSBpbiBpbmRpY2VzX2xpc3QpIHsKICB2aWRlb19uYW1lIDwtIGluZGljZXNfZmlsZSAlPiUgc3RyX3JlbW92ZSgiLy4qIikKICB0ZW1wIDwtIHJlYWRfY3N2KHBhc3RlMCgiLi4vMjAxOV8wM18wNl9Db3VydHNoaXAvIixpbmRpY2VzX2ZpbGUpKQogIHRlbXAgPC0gdGVtcCAlPiUKICAgIG11dGF0ZSh2aWRlbyA9IHZpZGVvX25hbWUpCiAgYWxsX2luZGljZXMgPC0gYmluZF9yb3dzKGFsbF9pbmRpY2VzLHRlbXApCn0KYWxsX2luZGljZXMKYGBgCgoKCgpgYGB7ciBtZXNzYWdlPUZBTFNFfQphbGxfbWFsZV9pbmRpY2VzIDwtIGxlZnRfam9pbih4ID0gZ2Vub3R5cGVzLHkgPSBhbGxfaW5kaWNlcyxieT1jKCJ2aWRlbyI9InZpZGVvIiwiZmx5X2lkIj0iRmx5SWQiKSkKYGBgCgoKCgpgYGB7cn0KYWxsX21hbGVfaW5kaWNlcyAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBzdW1tYXJpc2UobiA9IGxlbmd0aChnZW5vdHlwZSkpCmBgYAoKYGBge3J9CnVuaXF1ZShhbGxfbWFsZV9pbmRpY2VzJGdlbm90eXBlKQpgYGAKCgoKPGJyLz4KPGJyLz4KCgoKYGBge3IgbWVzc2FnZT1GQUxTRX0KZ2dwbG90KGFsbF9tYWxlX2luZGljZXMsYWVzKHg9Z2Vub3R5cGUseT1Db3VydHNoaXBJbmRleFdpdGhGYWNpbmcpKSArIAogIGdlb21fYm94cGxvdCgpCmBgYAoKCjxici8+Cjxici8+CgoKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0zfQpwMSA8LSBnZ3Bsb3QoYWxsX21hbGVfaW5kaWNlcyxhZXMoeD1nZW5vdHlwZSx5PUNvdXJ0c2hpcEluZGV4KSkgKyAKICBnZW9tX2JveHBsb3QoKQpwMiA8LSBnZ3Bsb3QoYWxsX21hbGVfaW5kaWNlcyxhZXMoeD1nZW5vdHlwZSx5PUNvdXJ0c2hpcEluZGV4V2l0aEZhY2luZykpICsgCiAgZ2VvbV9ib3hwbG90KCkKcDMgPC0gZ2dwbG90KGFsbF9tYWxlX2luZGljZXMsYWVzKHg9Z2Vub3R5cGUseT1Ub3RhbENDSSkpICsgCiAgZ2VvbV9ib3hwbG90KCkKcDQgPC0gZ2dwbG90KGFsbF9tYWxlX2luZGljZXMsYWVzKHg9Z2Vub3R5cGUseT1Ub3RhbENDSXdGYWNpbmcpKSArIAogIGdlb21fYm94cGxvdCgpCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIscDMscDQpLAogICAgICAgICAgIyBsYWJlbHMgPSBjKCJBcHByb2FjaGluZ0luZGV4IiwKICAgICAgICAgICMgICAgICAgICAgICAiQ29udGFjdEluZGV4IiwKICAgICAgICAgICMgICAgICAgICAgICAiRW5jaXJjbGluZ0luZGV4IiwKICAgICAgICAgICMgICAgICAgICAgICAiRmFjaW5nSW5kZXgiLAogICAgICAgICAgIyAgICAgICAgICAgICJUdXJuaW5nSW5kZXgiLAogICAgICAgICAgIyAgICAgICAgICAgICJXaW5nSW5kZXgiKSwKICAgICAgICAgICMgaGp1c3QgPSAxLAogICAgICAgICAgbmNvbCA9IDQsCiAgICAgICAgICBucm93ID0gMSkKYGBgCgoKPGJyLz4KPGJyLz4KCgoKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD04fQpwMSA8LSBnZ3Bsb3QoYWxsX21hbGVfaW5kaWNlcyxhZXMoeD1nZW5vdHlwZSx5PUFwcHJvYWNoaW5nSW5kZXgpKSArIAogIGdlb21fYm94cGxvdCgpCnAyIDwtIGdncGxvdChhbGxfbWFsZV9pbmRpY2VzLGFlcyh4PWdlbm90eXBlLHk9Q29udGFjdEluZGV4KSkgKyAKICBnZW9tX2JveHBsb3QoKQpwMyA8LSBnZ3Bsb3QoYWxsX21hbGVfaW5kaWNlcyxhZXMoeD1nZW5vdHlwZSx5PUVuY2lyY2xpbmdJbmRleCkpICsgCiAgZ2VvbV9ib3hwbG90KCkKcDQgPC0gZ2dwbG90KGFsbF9tYWxlX2luZGljZXMsYWVzKHg9Z2Vub3R5cGUseT1GYWNpbmdJbmRleCkpICsgCiAgZ2VvbV9ib3hwbG90KCkKcDUgPC0gZ2dwbG90KGFsbF9tYWxlX2luZGljZXMsYWVzKHg9Z2Vub3R5cGUseT1UdXJuaW5nSW5kZXgpKSArIAogIGdlb21fYm94cGxvdCgpCnA2IDwtIGdncGxvdChhbGxfbWFsZV9pbmRpY2VzLGFlcyh4PWdlbm90eXBlLHk9V2luZ0luZGV4KSkgKyAKICBnZW9tX2JveHBsb3QoKQpnZ2FycmFuZ2UocGxvdGxpc3QgPSBsaXN0KHAxLHAyLHAzLHA0LHA1LHA2KSwKICAgICAgICAgICMgbGFiZWxzID0gYygiQXBwcm9hY2hpbmdJbmRleCIsCiAgICAgICAgICAjICAgICAgICAgICAgIkNvbnRhY3RJbmRleCIsCiAgICAgICAgICAjICAgICAgICAgICAgIkVuY2lyY2xpbmdJbmRleCIsCiAgICAgICAgICAjICAgICAgICAgICAgIkZhY2luZ0luZGV4IiwKICAgICAgICAgICMgICAgICAgICAgICAiVHVybmluZ0luZGV4IiwKICAgICAgICAgICMgICAgICAgICAgICAiV2luZ0luZGV4IiksCiAgICAgICAgICAjIGhqdXN0ID0gMSwKICAgICAgICAgIG5jb2wgPSAzLAogICAgICAgICAgbnJvdyA9IDIpCmBgYAoKCgo8YnIvPgo8YnIvPgoKCgoKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD00fQpwMSA8LSBnZ3Bsb3QoYWxsX21hbGVfaW5kaWNlcyxhZXMoeD1nZW5vdHlwZSx5PUNvdXJ0c2hpcEluaXRpYXRpb24pKSArIAogIGdlb21fYm94cGxvdCgpCnAyIDwtIGdncGxvdChhbGxfbWFsZV9pbmRpY2VzLGFlcyh4PWdlbm90eXBlLHk9Q291cnRzaGlwVGVybWluYXRpb24pKSArIAogIGdlb21fYm94cGxvdCgpCnAzIDwtIGdncGxvdChhbGxfbWFsZV9pbmRpY2VzLGFlcyh4PWdlbm90eXBlLHk9Q291cnRzaGlwRHVyYXRpb24pKSArIAogIGdlb21fYm94cGxvdCgpCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIscDMpLAogICAgICAgICAgbmNvbCA9IDMsCiAgICAgICAgICBucm93ID0gMSkKYGBgCgoKPGJyLz4KPGJyLz4KCgoKYGBge3IgbWVzc2FnZT1GQUxTRX0KZGYgPC0gYWxsX21hbGVfaW5kaWNlcyAlPiUKICBzZWxlY3QoZ2Vub3R5cGUsQ291cnRzaGlwVGVybWluYXRpb24pICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIG11dGF0ZShsZW49bGVuZ3RoKENvdXJ0c2hpcFRlcm1pbmF0aW9uKSkKI2dncGxvdChkZixhZXMoeD1Db3VydHNoaXBUZXJtaW5hdGlvbixjb2xvcj1nZW5vdHlwZSkpICsgZ2VvbV9zdGVwKGFlcyhsZW49bGVuLHk9Li55Li4gKiBsZW4pLHN0YXQ9ImVjZGYiKSAKZ2dwbG90KGRmLGFlcyh4PUNvdXJ0c2hpcFRlcm1pbmF0aW9uLGNvbG9yPWdlbm90eXBlKSkgKyBnZW9tX3N0ZXAoYWVzKHk9Li55Li4pLHN0YXQ9ImVjZGYiKQpgYGAKCgo8YnIvPgo8YnIvPgoKCgpgYGB7ciBtZXNzYWdlPUZBTFNFfQpkZiA8LSBhbGxfbWFsZV9pbmRpY2VzICU+JQogIHNlbGVjdChnZW5vdHlwZSxDb3VydHNoaXBEdXJhdGlvbikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgbXV0YXRlKGxlbj1sZW5ndGgoQ291cnRzaGlwRHVyYXRpb24pKQojZ2dwbG90KGRmLGFlcyh4PUNvdXJ0c2hpcER1cmF0aW9uLGNvbG9yPWdlbm90eXBlKSkgKyBnZW9tX3N0ZXAoYWVzKGxlbj1sZW4seT0uLnkuLiAqIGxlbiksc3RhdD0iZWNkZiIpIApnZ3Bsb3QoZGYsYWVzKHg9Q291cnRzaGlwRHVyYXRpb24sY29sb3I9Z2Vub3R5cGUpKSArIGdlb21fc3RlcChhZXMoeT0uLnkuLiksc3RhdD0iZWNkZiIpCmBgYAoKCgoKPGJyLz4KPGJyLz4KCgoKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD04fQpwMSA8LSBnZ3Bsb3QoYWxsX21hbGVfaW5kaWNlcyxhZXMoeD1nZW5vdHlwZSx5PUFwcHJvYWNoaW5nQm91dExlbmd0aCkpICsgCiAgZ2VvbV9ib3hwbG90KCkKcDIgPC0gZ2dwbG90KGFsbF9tYWxlX2luZGljZXMsYWVzKHg9Z2Vub3R5cGUseT1Db250YWN0Qm91dExlbmd0aCkpICsgCiAgZ2VvbV9ib3hwbG90KCkKcDMgPC0gZ2dwbG90KGFsbF9tYWxlX2luZGljZXMsYWVzKHg9Z2Vub3R5cGUseT1FbmNpcmNsaW5nQm91dExlbmd0aCkpICsgCiAgZ2VvbV9ib3hwbG90KCkKcDQgPC0gZ2dwbG90KGFsbF9tYWxlX2luZGljZXMsYWVzKHg9Z2Vub3R5cGUseT1GYWNpbmdCb3V0TGVuZ3RoKSkgKyAKICBnZW9tX2JveHBsb3QoKQpwNSA8LSBnZ3Bsb3QoYWxsX21hbGVfaW5kaWNlcyxhZXMoeD1nZW5vdHlwZSx5PVR1cm5pbmdCb3V0TGVuZ3RoKSkgKyAKICBnZW9tX2JveHBsb3QoKQpwNiA8LSBnZ3Bsb3QoYWxsX21hbGVfaW5kaWNlcyxhZXMoeD1nZW5vdHlwZSx5PVdpbmdCb3V0TGVuZ3RoKSkgKyAKICBnZW9tX2JveHBsb3QoKQpwNyA8LSBnZ3Bsb3QoYWxsX21hbGVfaW5kaWNlcyxhZXMoeD1nZW5vdHlwZSx5PUFwcHJvYWNoaW5nQm91dEludGVydmFsKSkgKyAKICBnZW9tX2JveHBsb3QoKQpwOCA8LSBnZ3Bsb3QoYWxsX21hbGVfaW5kaWNlcyxhZXMoeD1nZW5vdHlwZSx5PUNvbnRhY3RCb3V0SW50ZXJ2YWwpKSArIAogIGdlb21fYm94cGxvdCgpCnA5IDwtIGdncGxvdChhbGxfbWFsZV9pbmRpY2VzLGFlcyh4PWdlbm90eXBlLHk9RW5jaXJjbGluZ0JvdXRJbnRlcnZhbCkpICsgCiAgZ2VvbV9ib3hwbG90KCkKcDEwIDwtIGdncGxvdChhbGxfbWFsZV9pbmRpY2VzLGFlcyh4PWdlbm90eXBlLHk9RmFjaW5nQm91dEludGVydmFsKSkgKyAKICBnZW9tX2JveHBsb3QoKQpwMTEgPC0gZ2dwbG90KGFsbF9tYWxlX2luZGljZXMsYWVzKHg9Z2Vub3R5cGUseT1UdXJuaW5nQm91dEludGVydmFsKSkgKyAKICBnZW9tX2JveHBsb3QoKQpwMTIgPC0gZ2dwbG90KGFsbF9tYWxlX2luZGljZXMsYWVzKHg9Z2Vub3R5cGUseT1XaW5nQm91dEludGVydmFsKSkgKyAKICBnZW9tX2JveHBsb3QoKQpnZ2FycmFuZ2UocGxvdGxpc3QgPSBsaXN0KHAxLHAyLHAzLHA0LHA1LHA2LAogICAgICAgICAgICAgICAgICAgICAgICAgIHA3LHA4LHA5LHAxMCxwMTEscDEyKSwKICAgICAgICAgICMgbGFiZWxzID0gYygiQXBwcm9hY2hpbmdJbmRleCIsCiAgICAgICAgICAjICAgICAgICAgICAgIkNvbnRhY3RJbmRleCIsCiAgICAgICAgICAjICAgICAgICAgICAgIkVuY2lyY2xpbmdJbmRleCIsCiAgICAgICAgICAjICAgICAgICAgICAgIkZhY2luZ0luZGV4IiwKICAgICAgICAgICMgICAgICAgICAgICAiVHVybmluZ0luZGV4IiwKICAgICAgICAgICMgICAgICAgICAgICAiV2luZ0luZGV4IiksCiAgICAgICAgICAjIGhqdXN0ID0gMSwKICAgICAgICAgIG5jb2wgPSA2LAogICAgICAgICAgbnJvdyA9IDIpCmBgYAoKCgoKCgoKCgoKCjxici8+Cjxici8+Cjxici8+Cjxici8+CgoKCgoKCgoKCgoKYGBge3IgIHdhcm5pbmc9RkFMU0V9CnJhd2RhdGFfbGlzdCA8LSBsaXN0LmZpbGVzKCIuLi8iLHJlY3Vyc2l2ZSA9IFRSVUUpICU+JSBzdHJfc3Vic2V0KCJfQUxMREFUQS5jc3YiKSAlPiUgc3RyX3N1YnNldCgiX01hbGVfIikKYWxsX3Jhd2RhdGEgPC0gdGliYmxlKCkKZm9yIChyYXdkYXRhX2ZpbGUgaW4gcmF3ZGF0YV9saXN0KSB7CiAgdGVtcCA8LSByZWFkX2NzdihwYXN0ZTAoIi4uLyIscmF3ZGF0YV9maWxlKSxwcm9ncmVzcyA9IEZBTFNFKQogIGFsbF9yYXdkYXRhIDwtIGJpbmRfcm93cyhhbGxfcmF3ZGF0YSx0ZW1wKQp9CmBgYAoKCgpgYGB7ciBtZXNzYWdlPUZBTFNFfQphbGxfcmF3ZGF0YSA8LSBhbGxfcmF3ZGF0YSAlPiUKICBmdWxsX2pvaW4oeCA9IGFsbF9yYXdkYXRhLCB5ID0gZ2Vub3R5cGVzLCBieSA9IGMoIkZpbGVOYW1lIj0idmlkZW8iLCJJZCI9ImZseV9pZCIpKSAlPiUgCiAgcmVwbGFjZV9uYShsaXN0KGdlbm90eXBlID0gIkNTIGZlbWFsZSIpKQphbGxfcmF3ZGF0YQpgYGAKCgoKCgo8YnIvPgo8YnIvPgoKCgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKEZpbGVOYW1lID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyMzRfMiIpICU+JSAKICBmaWx0ZXIoQXJlbmEgPT0gMikgJT4lIAogIGZpbHRlcihJZCA9PSAzKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGdncGxvdChhZXMoeD1GcmFtZSkpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9d2luZ19sX2FuZ19fcmFkLCBjb2xvdXIgPSAiI0Y4NzY2RCIpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PXdpbmdfcl9hbmdfX3JhZCwgY29sb3VyID0gIiMwMEJGQzQiKSkKICAKYGBgCgoKPGJyLz4KPGJyLz4KCgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCAgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihBcmVuYSA9PSAyKSAlPiUgCiAgZmlsdGVyKElkID09IDMpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZ2dwbG90KCkgKwogICAgZ2VvbV9kZW5zaXR5KGFlcyh4PXdpbmdfbF9hbmdfX3JhZCwgY29sb3VyID0gIiNGODc2NkQiKSxzaXplID0gMikgKwogICAgZ2VvbV9kZW5zaXR5KGFlcyh4PXdpbmdfcl9hbmdfX3JhZCwgY29sb3VyID0gIiMwMEJGQzQiKSxzaXplID0gMikKYGBgCgoKCjxici8+Cjxici8+CgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsICBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKEFyZW5hID09IDIpICU+JSAKICBmaWx0ZXIoSWQgPT0gMykgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lIAogIGdncGxvdCgpICsKICAgIGdlb21fZGVuc2l0eShhZXMoeD13aW5nX2xfYW5nX19yYWQsIGNvbG91ciA9ICIjRjg3NjZEIiksc2l6ZSA9IDIpICsKICAgIGdlb21fZGVuc2l0eShhZXMoeD13aW5nX3JfYW5nX19yYWQsIGNvbG91ciA9ICIjMDBCRkM0Iiksc2l6ZSA9IDIpCmBgYAoKCgoKCgoKCmBgYHtyfQojICMgRXh0cmFjdCBkZW5zaXR5IGRhdGEgdG8gYXZlcmFnZQojIHAgPC0gZ2dwbG90X2J1aWxkKHRlc3RfcGxvdCkKIyBnZ3Bsb3QoYXMuZGF0YS5mcmFtZShwJGRhdGFbWzFdXSksIGFlcyh4LHkpKSArIGdlb21fbGluZSgpCiMgZ2dwbG90KGFzLmRhdGEuZnJhbWUocCRkYXRhW1syXV0pLCBhZXMoeCx5KSkgKyBnZW9tX2xpbmUoKQpgYGAKCgoKPGJyLz4KPGJyLz4KCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsICBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSA9PSAiQSIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ2dwbG90KGFlcyh4PW1heF93aW5nX2FuZ19fcmFkLGNvbG91cj1pbmRpdmlkdWFsKSkgKwogICAgZ2VvbV9kZW5zaXR5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCmBgYAoKCgoKPGJyLz4KPGJyLz4KCgoKYGBge3Igd2FybmluZz1GQUxTRSwgIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlID09ICJCIikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBnZ3Bsb3QoYWVzKHg9bWF4X3dpbmdfYW5nX19yYWQsY29sb3VyPWluZGl2aWR1YWwpKSArCiAgICBnZW9tX2RlbnNpdHkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgoKCgo8YnIvPgo8YnIvPgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCAgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkMiKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdncGxvdChhZXMoeD1tYXhfd2luZ19hbmdfX3JhZCxjb2xvdXI9aW5kaXZpZHVhbCkpICsKICAgIGdlb21fZGVuc2l0eSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCgoKPGJyLz4KPGJyLz4KCgoKYGBge3Igd2FybmluZz1GQUxTRSwgIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlID09ICJEIikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBnZ3Bsb3QoYWVzKHg9bWF4X3dpbmdfYW5nX19yYWQsY29sb3VyPWluZGl2aWR1YWwpKSArCiAgICBnZW9tX2RlbnNpdHkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgoKCjxici8+Cjxici8+CgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsICBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKElkID09IDMpICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUseT1hbmdsZV9iZXR3ZWVuX19yYWQpKSArCiAgICBnZW9tX3BvaW50KCkKYGBgCgoKCgoKPGJyLz4KPGJyLz4KCgoKYGBge3Igd2FybmluZz1GQUxTRSwgIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKEZpbGVOYW1lID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyMzRfMiIpICU+JSAKICBmaWx0ZXIoQXJlbmEgPT0gMikgJT4lIAogIGdncGxvdChhZXMoeD1GcmFtZSx5PWZhY2luZ19hbmdsZV9fcmFkLCBjb2xvcj1hc19mYWN0b3IoSWQpKSkgKwogICAgZ2VvbV9wb2ludCgpCmBgYAoKCgoKPGJyLz4KPGJyLz4KCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsICBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKEFyZW5hID09IDIpICU+JSAKICBnZ3Bsb3QoKSArCiAgICBnZW9tX2RlbnNpdHkoYWVzKHg9ZmFjaW5nX2FuZ2xlX19yYWQsIGNvbG9yPWFzX2ZhY3RvcihJZCkpLHNpemUgPSAyKQpgYGAKCgoKCgo8YnIvPgo8YnIvPgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCAgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkEiKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdncGxvdChhZXMoeD1mYWNpbmdfYW5nbGVfX3JhZCxjb2xvdXI9aW5kaXZpZHVhbCkpICsKICAgIGdlb21fZGVuc2l0eSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgICB5bGltKDAsNikKYGBgCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsICBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcih1bmlxdWVfZmx5ID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyMzRfNl8xNyIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIGdncGxvdChhZXMoeD1mYWNpbmdfYW5nbGVfX3JhZCxjb2xvdXI9dW5pcXVlX2ZseSkpICsKICAgIGdlb21fZGVuc2l0eSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgICB5bGltKDAsNikKYGBgCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCAgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIodW5pcXVlX2ZseSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzZfMTciKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICBnZ3Bsb3QoYWVzKHg9RnJhbWUseT1mYWNpbmdfYW5nbGVfX3JhZCxjb2xvdXI9dW5pcXVlX2ZseSkpICsKICAgIGdlb21fcG9pbnQoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgIysKICAgICN5bGltKDAsNikKYGBgCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCAgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIodW5pcXVlX2ZseSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzZfMTciKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICBnZ3Bsb3QoYWVzKHg9RnJhbWUseT1kaXN0X3RvX290aGVyX19tbSxjb2xvdXI9dW5pcXVlX2ZseSkpICsKICAgIGdlb21fcG9pbnQoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgIysKICAgICN5bGltKDAsNikKYGBgCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsICBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcih1bmlxdWVfZmx5ID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyMzRfNl8xNyIpICU+JSAKICBmaWx0ZXIoU21vb3RoZWRDb3B1bGF0aW9uID09IDApICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgZ2dwbG90KGFlcyh4PWZhY2luZ19hbmdsZV9fcmFkLGNvbG91cj11bmlxdWVfZmx5KSkgKwogICAgZ2VvbV9kZW5zaXR5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICAgIHlsaW0oMCw2KQpgYGAKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCAgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIodW5pcXVlX2ZseSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzZfMTciKSAlPiUgCiAgZmlsdGVyKEZyYW1lIDwgNTAwMCkgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICBnZ3Bsb3QoYWVzKHg9ZmFjaW5nX2FuZ2xlX19yYWQsY29sb3VyPXVuaXF1ZV9mbHkpKSArCiAgICBnZW9tX2RlbnNpdHkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogICAgeWxpbSgwLDYpCmBgYAoKYGBge3Igd2FybmluZz1GQUxTRSwgIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKHVuaXF1ZV9mbHkgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF82XzE3IikgJT4lIAogIGdncGxvdChhZXMoeD1GcmFtZSx5PWRpc3RfdG9fb3RoZXJfX21tKSkgKwogICAgZ2VvbV9wb2ludChhZXMoY29sb3VyPWMoaWZlbHNlKFNtb290aGVkRGlzdFRvT3RoZXI+MC41LCJub3QgY29wdWxhdGluZyIsImNvcHVsYXRpbmciKSkpKSsKICAgIGdlb21fcG9pbnQoYWVzKHk9YyhpZmVsc2UoU21vb3RoZWRDb3B1bGF0aW9uPT0xLFNtb290aGVkQ29wdWxhdGlvbis2LE5BKSkpKSsKICAgIGdlb21fcG9pbnQoYWVzKHk9YyhpZmVsc2UoQ29wdWxhdGlvbj09MSxDb3B1bGF0aW9uKzcsTkEpKSkpCmBgYAoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKHVuaXF1ZV9mbHkgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF85XzM5IikgJT4lIAogIGdncGxvdChhZXMoeD1GcmFtZSx5PWRpc3RfdG9fb3RoZXJfX21tKSkgKwogICAgZ2VvbV9wb2ludChhZXMoY29sb3VyPWMoaWZlbHNlKFNtb290aGVkRGlzdFRvT3RoZXI+MC41LCJub3QgY29wdWxhdGluZyIsImNvcHVsYXRpbmciKSkpKSsKICAgIGdlb21fcG9pbnQoYWVzKHk9YyhpZmVsc2UoU21vb3RoZWRDb3B1bGF0aW9uPT0xLFNtb290aGVkQ29wdWxhdGlvbis2LE5BKSkpKSsKICAgIGdlb21fcG9pbnQoYWVzKHk9YyhpZmVsc2UoQ29wdWxhdGlvbj09MSxDb3B1bGF0aW9uKzcsTkEpKSkpCmBgYAoKCgoKCgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCAgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkEiKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIHN1bW1hcmlzZShpZCA9IHVuaXF1ZSh1bmlxdWVfZmx5KSwKICAgICAgICAgICAgZmFjaW5nID0gbWVhbihmYWNpbmdfYW5nbGVfX3JhZCkpICAKYGBgCgoKCgoKCgoKCgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlID09ICJCIikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBnZ3Bsb3QoYWVzKHg9ZmFjaW5nX2FuZ2xlX19yYWQsY29sb3VyPWluZGl2aWR1YWwpKSArCiAgICBnZW9tX2RlbnNpdHkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogICAgeWxpbSgwLDYpCmBgYAoKYGBge3Igd2FybmluZz1GQUxTRSwgIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlID09ICJDIikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBnZ3Bsb3QoYWVzKHg9ZmFjaW5nX2FuZ2xlX19yYWQsY29sb3VyPWluZGl2aWR1YWwpKSArCiAgICBnZW9tX2RlbnNpdHkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogICAgeWxpbSgwLDYpCmBgYAoKCgo8YnIvPgo8YnIvPgoKCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsICBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSA9PSAiRCIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWZhY2luZ19hbmdsZV9fcmFkLGNvbG91cj1pbmRpdmlkdWFsKSkgKwogICAgZ2VvbV9kZW5zaXR5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICAgIHlsaW0oMCw2KQpgYGAKCgoKPGJyLz4KPGJyLz4KCgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCAgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkEiKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogICNmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBnZ3Bsb3QoYWVzKHg9ZmFjaW5nX2FuZ2xlX19yYWQsY29sb3VyPWluZGl2aWR1YWwpKSArCiAgICBnZW9tX2RlbnNpdHkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogICAgeWxpbSgwLDYpCmBgYAoKCgoKPGJyLz4KPGJyLz4KCgoKYGBge3Igd2FybmluZz1GQUxTRSwgIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlID09ICJEIikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICAjZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWZhY2luZ19hbmdsZV9fcmFkLGNvbG91cj1pbmRpdmlkdWFsKSkgKwogICAgZ2VvbV9kZW5zaXR5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICAgIHlsaW0oMCw2KQpgYGAKCgoKCjxici8+Cjxici8+CgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCAgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihBcmVuYSA9PSAyKSAlPiUgCiAgZ2dwbG90KGFlcyh4PUZyYW1lLHk9ZGlzdF90b19vdGhlcl9fbW0sIGNvbG9yPWRpc3RfdG9fb3RoZXJfX21tKSkgKwogICAgZ2VvbV9wb2ludCgpIApgYGAKCgo8YnIvPgo8YnIvPgoKCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsICBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKElkID09IDMpICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUseT1kaXN0X3RvX290aGVyX19tbSkpICsKICAgIGdlb21fcG9pbnQoYWVzKGNvbG91cj1jKGlmZWxzZShkaXN0X3RvX290aGVyX19tbT4yLCJub3QgY29wdWxhdGluZyIsImNvcHVsYXRpbmciKSkpKQpgYGAKCgoKCgo8YnIvPgo8YnIvPgoKCjxici8+Cjxici8+CgoKCgoKCiMjIyBEIGdlbm90eXBlIGRpc3RhbmNlIHRvIG90aGVyCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCAgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihJZCA9PSAyNykgJT4lIAogIGdncGxvdChhZXMoeD1GcmFtZSx5PWRpc3RfdG9fb3RoZXJfX21tKSkgKwogICAgZ2VvbV9wb2ludChhZXMoY29sb3VyPWMoaWZlbHNlKGRpc3RfdG9fb3RoZXJfX21tPjIsIm5vdCBjb3B1bGF0aW5nIiwiY29wdWxhdGluZyIpKSkpCmBgYAoKCgo8YnIvPgo8YnIvPgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKEZpbGVOYW1lID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyMzRfMiIpICU+JSAKICBmaWx0ZXIoSWQgPT0gMjkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUseT1kaXN0X3RvX290aGVyX19tbSkpICsKICAgIGdlb21fcG9pbnQoYWVzKGNvbG91cj1jKGlmZWxzZShkaXN0X3RvX290aGVyX19tbT4yLCJub3QgY29wdWxhdGluZyIsImNvcHVsYXRpbmciKSkpKQpgYGAKCgo8YnIvPgo8YnIvPgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKEZpbGVOYW1lID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyMzRfMiIpICU+JSAKICBmaWx0ZXIoSWQgPT0gMzUpICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUseT1kaXN0X3RvX290aGVyX19tbSkpICsKICAgIGdlb21fcG9pbnQoYWVzKGNvbG91cj1jKGlmZWxzZShkaXN0X3RvX290aGVyX19tbT4yLCJub3QgY29wdWxhdGluZyIsImNvcHVsYXRpbmciKSkpKQpgYGAKCgoKPGJyLz4KPGJyLz4KCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsICBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKElkID09IDM3KSAlPiUgCiAgZ2dwbG90KGFlcyh4PUZyYW1lLHk9ZGlzdF90b19vdGhlcl9fbW0pKSArCiAgICBnZW9tX3BvaW50KGFlcyhjb2xvdXI9YyhpZmVsc2UoZGlzdF90b19vdGhlcl9fbW0+Miwibm90IGNvcHVsYXRpbmciLCJjb3B1bGF0aW5nIikpKSkKYGBgCgoKCgoKPGJyLz4KPGJyLz4KCgoKCgpgYGB7cn0KYWxsX3Jhd2RhdGEgPC0gYWxsX3Jhd2RhdGEgJT4lICAKICB1bml0ZSgidW5pcXVlX2ZseSIsRmlsZU5hbWUsSWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIG11dGF0ZSgKICAgIE11bHRpdGFza2luZyA9IChBcHByb2FjaGluZyArIEVuY2lyY2xpbmcgKyBDb250YWN0ICsgVHVybmluZyArIFdpbmdHZXN0dXJlKSwKICAgIE11bHRpdGFza2luZ1dpdGhGYWNpbmcgPSAoQXBwcm9hY2hpbmcgKyBFbmNpcmNsaW5nICsgRmFjaW5nICsgQ29udGFjdCArIFR1cm5pbmcgKyBXaW5nR2VzdHVyZSksCiAgICBDb3VydHNoaXAgPSBpZmVsc2UoTXVsdGl0YXNraW5nPj0xLCAxLCAwKSwKICAgIENvdXJ0c2hpcFdpdGhGYWNpbmcgPSBpZmVsc2UoTXVsdGl0YXNraW5nV2l0aEZhY2luZz49MSwgMSwgMCksCiAgICBNdWx0aXRhc2tpbmdXaXRoQ29wdWxhdGlvbiA9IChBcHByb2FjaGluZyArIEVuY2lyY2xpbmcgKyBDb250YWN0ICsgVHVybmluZyArIFdpbmdHZXN0dXJlICsgQ29wdWxhdGlvbiksCiAgICBNdWx0aXRhc2tpbmdXaXRoQ29wdWxhdGlvbldpdGhGYWNpbmcgPSAoQXBwcm9hY2hpbmcgKyBFbmNpcmNsaW5nICsgRmFjaW5nICsgQ29udGFjdCArIFR1cm5pbmcgKyBXaW5nR2VzdHVyZSArIENvcHVsYXRpb24pLAogICAgQ291cnRzaGlwQW5kQ29wdWxhdGlvbiA9IGlmZWxzZShNdWx0aXRhc2tpbmdXaXRoQ29wdWxhdGlvbj49MSwgMSwgMCksCiAgICBDb3VydHNoaXBBbmRDb3B1bGF0aW9uV3RoRmFjaW5nID0gaWZlbHNlKE11bHRpdGFza2luZ1dpdGhDb3B1bGF0aW9uV2l0aEZhY2luZz49MSwgMSwgMCksCiAgICBTbW9vdGhlZENvdXJ0c2hpcCA9IGlmZWxzZSgocm9sbG1lYW4oQ291cnRzaGlwLCAxNTAsIGZpbGwgPSBjKDAsMCwwKSwgYWxpZ24gPSBjKCJsZWZ0IikpKT4wLjUsIDEsIDApLAogICAgU21vb3RoZWRDb3B1bGF0aW9uID0gaWZlbHNlKChyb2xsbWVhbihDb3B1bGF0aW9uLCAxMjUwLCBmaWxsID0gYygwLDAsMCksIGFsaWduID0gYygiY2VudGVyIikpKT4wLjUsIDEsIDApLAogICAgU21vb3RoZWREaXN0VG9PdGhlciA9IGlmZWxzZSgocm9sbG1lYW4oaWZlbHNlKGRpc3RfdG9fb3RoZXJfX21tID4gMiwgMSwgMCksIDI1MCwgZmlsbCA9IGMoMSwxLE5BKSwgYWxpZ24gPSBjKCJjZW50ZXIiKSkpPjAuNSwgMSwgMCkKKQpgYGAKCgoKCgoKPGJyLz4KPGJyLz4KCgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKEZpbGVOYW1lID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyMzRfMiIpICU+JSAKICBmaWx0ZXIoSWQgPT0gMzcpICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUseT1kaXN0X3RvX290aGVyX19tbSkpICsKICAgIGdlb21fcG9pbnQoYWVzKGNvbG91cj1jKGlmZWxzZShTbW9vdGhlZERpc3RUb090aGVyPT0xLCJub3QgY29wdWxhdGluZyIsImNvcHVsYXRpbmciKSkpKQpgYGAKCgoKPGJyLz4KPGJyLz4KCgoKYGBge3Igd2FybmluZz1GQUxTRSwgIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKEZpbGVOYW1lID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyMzRfMiIpICU+JSAKICBmaWx0ZXIoSWQgPT0gMzcpICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PVNtb290aGVkRGlzdFRvT3RoZXIsIGNvbG91ciA9ICIjRjg3NjZEIikpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9KFNtb290aGVkQ29wdWxhdGlvbiswLjEpLCBjb2xvdXI9ICIjMDBCRkM0IikpCiAgICAKYGBgCgoKCgo8YnIvPgo8YnIvPgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCAgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihJZCA9PSAzNSkgJT4lIAogIGdncGxvdChhZXMoeD1GcmFtZSx5PWRpc3RfdG9fb3RoZXJfX21tKSkgKwogICAgZ2VvbV9wb2ludChhZXMoY29sb3VyPWMoaWZlbHNlKFNtb290aGVkRGlzdFRvT3RoZXI9PTEsIm5vdCBjb3B1bGF0aW5nIiwiY29wdWxhdGluZyIpKSkpCmBgYAoKCgoKCjxici8+Cjxici8+CgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCAgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihJZCA9PSAzNSkgJT4lIAogIGdncGxvdChhZXMoeD1GcmFtZSkpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9U21vb3RoZWREaXN0VG9PdGhlciwgY29sb3VyID0gIiNGODc2NkQiKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT0oU21vb3RoZWRDb3B1bGF0aW9uKzAuMSksIGNvbG91cj0gIiMwMEJGQzQiKSkKICAgIApgYGAKCgoKCjxici8+Cjxici8+CgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKEZpbGVOYW1lID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyMzRfMiIpICU+JSAKICBmaWx0ZXIoSWQgPT0gMzUpICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PVNtb290aGVkRGlzdFRvT3RoZXIsIGNvbG91ciA9ICIjRjg3NjZEIikpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9KFNtb290aGVkQ29wdWxhdGlvbiswLjEpLCBjb2xvdXI9ICIjMDBCRkM0IikpICsKICAgIHhsaW0oMjAwMCwzMDAwKQpgYGAKCgo8YnIvPgo8YnIvPgoKCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsICBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKElkID09IDM1KSAlPiUgCiAgc3VtbWFyaXNlKHdoaWNoLm1pbihTbW9vdGhlZERpc3RUb090aGVyKSwKICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikpCmBgYAoKCgoKCgoKCjxici8+Cjxici8+CgoKCgoKCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsICBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKElkID09IDMpICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUseT1kaXN0X3RvX290aGVyX19tbSkpICsKICAgIGdlb21fcG9pbnQoYWVzKGNvbG91cj1jKGlmZWxzZShTbW9vdGhlZERpc3RUb090aGVyPT0xLCJub3QgY29wdWxhdGluZyIsImNvcHVsYXRpbmciKSkpKQpgYGAKCgoKCgo8YnIvPgo8YnIvPgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCAgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihJZCA9PSAzKSAlPiUgCiAgZ2dwbG90KGFlcyh4PUZyYW1lLHk9ZGlzdF90b19vdGhlcl9fbW0pKSArCiAgICBnZW9tX3BvaW50KGFlcyhjb2xvdXI9YyhpZmVsc2UoU21vb3RoZWRDb3B1bGF0aW9uPT0wLCJub3QgY29wdWxhdGluZyIsImNvcHVsYXRpbmciKSkpKQpgYGAKCgoKCjxici8+Cjxici8+CgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsICBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKElkID09IDMpICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PVNtb290aGVkRGlzdFRvT3RoZXIsIGNvbG91ciA9ICIjRjg3NjZEIikpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9KFNtb290aGVkQ29wdWxhdGlvbiswLjEpLCBjb2xvdXI9ICIjMDBCRkM0IikpICsKICAgIHhsaW0oNjAwMCw3MDAwKQpgYGAKCgoKPGJyLz4KPGJyLz4KCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsICBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKElkID09IDMpICU+JSAKICBzdW1tYXJpc2Uod2hpY2gubWluKFNtb290aGVkRGlzdFRvT3RoZXIpLAogICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSkKYGBgCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCgoKCiMjIyBEIGdlbm90eXBlIGRpc3RhbmNlIHRvIG90aGVyCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKElkID09IDI3KSAlPiUgCiAgZ2dwbG90KGFlcyh4PUZyYW1lLHk9ZGlzdF90b19vdGhlcl9fbW0pKSArCiAgICBnZW9tX3BvaW50KGFlcyhjb2xvdXI9YyhpZmVsc2UoU21vb3RoZWREaXN0VG9PdGhlcj09MSwibm90IGNvcHVsYXRpbmciLCJjb3B1bGF0aW5nIikpKSkKYGBgCgoKCjxici8+Cjxici8+CgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKElkID09IDI5KSAlPiUgCiAgZ2dwbG90KGFlcyh4PUZyYW1lLHk9ZGlzdF90b19vdGhlcl9fbW0pKSArCiAgICBnZW9tX3BvaW50KGFlcyhjb2xvdXI9YyhpZmVsc2UoU21vb3RoZWREaXN0VG9PdGhlcj09MSwibm90IGNvcHVsYXRpbmciLCJjb3B1bGF0aW5nIikpKSkKYGBgCgoKPGJyLz4KPGJyLz4KCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihJZCA9PSAzNSkgJT4lIAogIGdncGxvdChhZXMoeD1GcmFtZSx5PWRpc3RfdG9fb3RoZXJfX21tKSkgKwogICAgZ2VvbV9wb2ludChhZXMoY29sb3VyPWMoaWZlbHNlKFNtb290aGVkRGlzdFRvT3RoZXI+MC41LCJub3QgY29wdWxhdGluZyIsImNvcHVsYXRpbmciKSkpKQpgYGAKCgoKPGJyLz4KPGJyLz4KCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKEZpbGVOYW1lID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyMzRfMiIpICU+JSAKICBmaWx0ZXIoSWQgPT0gMzcpICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUseT1kaXN0X3RvX290aGVyX19tbSkpICsKICAgIGdlb21fcG9pbnQoYWVzKGNvbG91cj1jKGlmZWxzZShTbW9vdGhlZERpc3RUb090aGVyPT0xLCJub3QgY29wdWxhdGluZyIsImNvcHVsYXRpbmciKSkpKQpgYGAKCgoKCgoKCgoKCgoKCgoKCgoKCgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCgoKCgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSA9PSAiRCIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ2dwbG90KGFlcyh4PW1heF93aW5nX2FuZ19fcmFkLGNvbG91cj1pbmRpdmlkdWFsKSkgKwogICAgZ2VvbV9kZW5zaXR5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICAgIHlsaW0oMCw2KSArCiAgICB4bGltKDAscGkpCmBgYAoKCgoKPGJyLz4KPGJyLz4KCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlID09ICJBIikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBnZ3Bsb3QoYWVzKHg9YW5nbGVfYmV0d2Vlbl9fcmFkLGNvbG91cj1pbmRpdmlkdWFsKSkgKwogICAgZ2VvbV9kZW5zaXR5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICAgIHlsaW0oMCwzKSArCiAgICB4bGltKDAscGkpCmBgYAoKCjxici8+Cjxici8+CgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlID09ICJEIikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBnZ3Bsb3QoYWVzKHg9YW5nbGVfYmV0d2Vlbl9fcmFkLGNvbG91cj1pbmRpdmlkdWFsKSkgKwogICAgZ2VvbV9kZW5zaXR5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICAgIHlsaW0oMCwzKSArCiAgICB4bGltKDAscGkpCmBgYAoKCgoKPGJyLz4KPGJyLz4KCgoKCgoKCgojIyMgKipEaXN0YW5jZSB0byB3YWxsKioKCgoKCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlID09ICJBIikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICAjZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWRpc3RfdG9fd2FsbF9fbW0sY29sb3VyPWluZGl2aWR1YWwpKSArCiAgICBnZW9tX2RlbnNpdHkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogICAgeWxpbSgwLDIuMikgKwogICAgeGxpbSgwLDEwKQpgYGAKCgoKCgo8YnIvPgo8YnIvPgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkQiKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogICNmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBnZ3Bsb3QoYWVzKHg9ZGlzdF90b193YWxsX19tbSxjb2xvdXI9aW5kaXZpZHVhbCkpICsKICAgIGdlb21fZGVuc2l0eSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgICB5bGltKDAsMi4yKSArCiAgICB4bGltKDAsMTApCmBgYAoKCgoKPGJyLz4KPGJyLz4KCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTZ9CnAxIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBzdW1tYXJpc2UoZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpLAogICAgICAgICAgICBtZWFuX2Rpc3RfdG9fd2FsbF9tbSA9IG1lYW4oZGlzdF90b193YWxsX19tbVt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqNjAwKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSo2MDApKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9bWVhbl9kaXN0X3RvX3dhbGxfbW0pKSArCiAgICBnZW9tX2JveHBsb3QoKQpwMiA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBncm91cF9ieSh1bmlxdWVfZmx5KSAlPiUgCiAgc3VtbWFyaXNlKGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSwKICAgICAgICAgICAgbWVkaWFuX2Rpc3RfdG9fd2FsbF9tbSA9IG1lZGlhbihkaXN0X3RvX3dhbGxfX21tW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSo2MDApKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqNjAwKSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICApICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUseT1tZWRpYW5fZGlzdF90b193YWxsX21tKSkgKwogICAgZ2VvbV9ib3hwbG90KCkKcDMgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIHN1bW1hcmlzZShnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksCiAgICAgICAgICAgIHByb3BfZGlzdF90b193YWxsX2x0XzEgPSAxMDAqc3VtKGRpc3RfdG9fd2FsbF9fbW1bd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPD0gKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSo2MDApKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqNjAwKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXTwxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYS5ybSA9IFRSVUUpLwogICAgICAgICAgICAgIGxlbmd0aChGcmFtZVt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqNjAwKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSo2MDApKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgICAgICAgICkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUseT1wcm9wX2Rpc3RfdG9fd2FsbF9sdF8xKSkgKwogICAgZ2VvbV9ib3hwbG90KCkKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMixwMyksCiAgICAgICAgICBsYWJlbHMgPSBjKCJNZWFuIERpc3RhbmNlIHRvIFdhbGwiLAogICAgICAgICAgICAgICAgICAgICAiTWVkaWFuIERpc3RhbmNlIHRvIFdhbGwiLAogICAgICAgICAgICAgICAgICAgICAiUHJvcCBUaW1lIENsb3NlIHRvIFdhbGwiKSwKICAgICAgICAgIGhqdXN0ID0gLTAuMiwKICAgICAgICAgIG5jb2wgPSAzLAogICAgICAgICAgbnJvdyA9IDEpCgpgYGAKCgoKCgoKCgoKCgoKCgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTZ9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBncm91cF9ieSh1bmlxdWVfZmx5KSAlPiUgCiAgZ2dwbG90KGFlcyh4PXBvc194X19weCx5PXBvc195X19weCkpICsKICAgIGdlb21fcG9pbnQoKQpgYGAKCgoKCgoKYGBge3J9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihJZCA9PSAzNikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBnZ3Bsb3QoYWVzKHg9cG9zX3hfX3B4LHk9cG9zX3lfX3B4KSkgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIGNvb3JkX2ZpeGVkKCkKYGBgCgoKCgoKYGBge3J9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihJZCA9PSAzNikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b193YWxsX19tbSA+IDEpICU+JSAKICBnZ3Bsb3QoYWVzKHg9cG9zX3hfX3B4LHk9cG9zX3lfX3B4KSkgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIGNvb3JkX2ZpeGVkKCkKYGBgCgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9Nn0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKElkID09IDM2KSAlPiUgCiAgI2ZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICAjZmlsdGVyKGRpc3RfdG9fd2FsbF9fbW0gPiAxKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9ZGlzdF90b193YWxsX19tbSkpICsKICAgIGdlb21fYm94cGxvdCgpICsKICB5bGltKDAsMTApCnAyIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihJZCA9PSAzNikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICAjZmlsdGVyKGRpc3RfdG9fd2FsbF9fbW0gPiAxKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9ZGlzdF90b193YWxsX19tbSkpICsKICAgIGdlb21fYm94cGxvdCgpICsKICB5bGltKDAsMTApCnAzIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihJZCA9PSAzNikgJT4lIAogICNmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fd2FsbF9fbW0gPiAxKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9ZGlzdF90b193YWxsX19tbSkpICsKICAgIGdlb21fYm94cGxvdCgpICsKICB5bGltKDAsMTApCnA0IDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihJZCA9PSAzNikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b193YWxsX19tbSA+IDEpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUseT1kaXN0X3RvX3dhbGxfX21tKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogIHlsaW0oMCwxMCkKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMixwMyxwNCksCiAgICAgICAgICBsYWJlbHMgPSBjKCJhbGwgZnJhbWVzIiwKICAgICAgICAgICAgICAgICAgICAgIm5vbiBjb3AgZnJhbWVzIiwKICAgICAgICAgICAgICAgICAgICAgImd0IDFtbSBmcm9tIHdhbGwiLAogICAgICAgICAgICAgICAgICAgICAibm9uIGNvcCwgZ3QgMW1tIiksCiAgICAgICAgICBoanVzdCA9IC0wLjQsCiAgICAgICAgICBuY29sID0gNCwKICAgICAgICAgIG5yb3cgPSAxKQoKYGBgCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo8YnIvPgo8YnIvPgoKCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlID09ICJBIikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBnZ3Bsb3QoYWVzKHg9ZGlzdF90b19vdGhlcl9fbW0sY29sb3VyPWluZGl2aWR1YWwpKSArCiAgICBnZW9tX2RlbnNpdHkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogICAgeWxpbSgwLDIpICsKICAgIHhsaW0oMCwyMCkKYGBgCgoKCgo8YnIvPgo8YnIvPgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkIiKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdncGxvdChhZXMoeD1kaXN0X3RvX290aGVyX19tbSxjb2xvdXI9aW5kaXZpZHVhbCkpICsKICAgIGdlb21fZGVuc2l0eSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgICB5bGltKDAsMikgKwogICAgeGxpbSgwLDIwKQpgYGAKCgo8YnIvPgo8YnIvPgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkMiKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdncGxvdChhZXMoeD1kaXN0X3RvX290aGVyX19tbSxjb2xvdXI9aW5kaXZpZHVhbCkpICsKICAgIGdlb21fZGVuc2l0eSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgICB5bGltKDAsMikgKwogICAgeGxpbSgwLDIwKQpgYGAKCgoKCgo8YnIvPgo8YnIvPgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkQiKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdncGxvdChhZXMoeD1kaXN0X3RvX290aGVyX19tbSxjb2xvdXI9aW5kaXZpZHVhbCkpICsKICAgIGdlb21fZGVuc2l0eSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgICB5bGltKDAsMikgKwogICAgeGxpbSgwLDIwKQpgYGAKCgoKCjxici8+Cjxici8+CgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIHN1bW1hcmlzZShtZWFuX2Rpc3RfdG9fb3RoZXIgPSBtZWFuKGRpc3RfdG9fb3RoZXJfX21tKSkKCgpgYGAKCgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCgojIyMgKiptZWFuIGRpc3RhbmNlIHRvIG90aGVyKioKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD00fQpwMSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgI2ZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9kaXN0X3RvX290aGVyID0gbWVhbihkaXN0X3RvX290aGVyX19tbSksCiAgICAgICAgICAgIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSwgeT1tZWFuX2Rpc3RfdG9fb3RoZXIpKSArCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICB5bGltKDAsMTApCnAyIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fZGlzdF90b19vdGhlciA9IG1lYW4oZGlzdF90b19vdGhlcl9fbW0pLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9bWVhbl9kaXN0X3RvX290aGVyKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgeWxpbSgwLDEwKQpwMyA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkIDwgKDM1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX2Rpc3RfdG9fb3RoZXIgPSBtZWFuKGRpc3RfdG9fb3RoZXJfX21tKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PW1lYW5fZGlzdF90b19vdGhlcikpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCwxMCkKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMixwMyksCiAgICAgICAgICBsYWJlbHMgPSBjKCJBbGwgRnJhbWVzIiwiV2luZyBFeHRlbnNpb24gRnJhbWVzIiwiTm9uLVdpbmcgRXh0ZW5zaW9uIEZyYW1lcyIpLAogICAgICAgICAgI2hqdXN0ID0gMSwKICAgICAgICAgIG5jb2wgPSAzLAogICAgICAgICAgbnJvdyA9IDEpCgpgYGAKCgo8YnIvPgo8YnIvPgoKCjxici8+Cjxici8+CgoKCiMjIyAqKm1lZGlhbiBkaXN0YW5jZSB0byBvdGhlcioqCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9NH0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogICNmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKG1lZGlhbl9kaXN0X3RvX290aGVyID0gbWVkaWFuKGRpc3RfdG9fb3RoZXJfX21tKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PW1lZGlhbl9kaXN0X3RvX290aGVyKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgeWxpbSgwLDEwKQpwMiA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDM1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lIAogIHN1bW1hcmlzZShtZWRpYW5fZGlzdF90b19vdGhlciA9IG1lZGlhbihkaXN0X3RvX290aGVyX19tbSksCiAgICAgICAgICAgIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSwgeT1tZWRpYW5fZGlzdF90b19vdGhlcikpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCwxMCkKcDMgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA8ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UobWVkaWFuX2Rpc3RfdG9fb3RoZXIgPSBtZWRpYW4oZGlzdF90b19vdGhlcl9fbW0pLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9bWVkaWFuX2Rpc3RfdG9fb3RoZXIpKSArCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICB5bGltKDAsMTApCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIscDMpLAogICAgICAgICAgbGFiZWxzID0gYygiQWxsIEZyYW1lcyIsIldpbmcgRXh0ZW5zaW9uIEZyYW1lcyIsIk5vbi1XaW5nIEV4dGVuc2lvbiBGcmFtZXMiKSwKICAgICAgICAgIGhqdXN0ID0gLTAuNCwKICAgICAgICAgIG5jb2wgPSAzLAogICAgICAgICAgbnJvdyA9IDEpCgpgYGAKCgoKCgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCgoKIyMjICoqbWVhbiBmYWNpbmcgYW5nbGUqKiAKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9NH0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogICNmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fZmFjaW5nX2FuZ2xlID0gbWVhbihmYWNpbmdfYW5nbGVfX3JhZCksCiAgICAgICAgICAgIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSwgeT1tZWFuX2ZhY2luZ19hbmdsZSkpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCxwaSkKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9mYWNpbmdfYW5nbGUgPSBtZWFuKGZhY2luZ19hbmdsZV9fcmFkKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PW1lYW5fZmFjaW5nX2FuZ2xlKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgeWxpbSgwLHBpKQpwMyA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkIDwgKDM1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX2ZhY2luZ19hbmdsZSA9IG1lYW4oZmFjaW5nX2FuZ2xlX19yYWQpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9bWVhbl9mYWNpbmdfYW5nbGUpKSArCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICB5bGltKDAscGkpCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIscDMpLAogICAgICAgICAgbGFiZWxzID0gYygiQWxsIEZyYW1lcyIsIldpbmcgRXh0ZW5zaW9uIEZyYW1lcyIsIk5vbi1XaW5nIEV4dGVuc2lvbiBGcmFtZXMiKSwKICAgICAgICAgICNoanVzdCA9IDEsCiAgICAgICAgICBuY29sID0gMywKICAgICAgICAgIG5yb3cgPSAxKQoKYGBgCgoKCgoKCgoKCgo8YnIvPgo8YnIvPgoKCjxici8+Cjxici8+CgoKCgojIyMgKiptZWRpYW4gZmFjaW5nIGFuZ2xlKioKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTR9CnAxIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICAjZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDM1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lIAogIHN1bW1hcmlzZShtZWRpYW5fZmFjaW5nX2FuZ2xlID0gbWVkaWFuKGZhY2luZ19hbmdsZV9fcmFkKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PW1lZGlhbl9mYWNpbmdfYW5nbGUpKSArCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICB5bGltKDAscGkpCnAyIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKG1lZGlhbl9mYWNpbmdfYW5nbGUgPSBtZWRpYW4oZmFjaW5nX2FuZ2xlX19yYWQpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9bWVkaWFuX2ZhY2luZ19hbmdsZSkpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCxwaSkKcDMgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA8ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UobWVkaWFuX2ZhY2luZ19hbmdsZSA9IG1lZGlhbihmYWNpbmdfYW5nbGVfX3JhZCksCiAgICAgICAgICAgIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSwgeT1tZWRpYW5fZmFjaW5nX2FuZ2xlKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgeWxpbSgwLHBpKQpnZ2FycmFuZ2UocGxvdGxpc3QgPSBsaXN0KHAxLHAyLHAzKSwKICAgICAgICAgIGxhYmVscyA9IGMoIkFsbCBGcmFtZXMiLCJXaW5nIEV4dGVuc2lvbiBGcmFtZXMiLCJOb24tV2luZyBFeHRlbnNpb24gRnJhbWVzIiksCiAgICAgICAgICAjaGp1c3QgPSAxLAogICAgICAgICAgbmNvbCA9IDMsCiAgICAgICAgICBucm93ID0gMSkKCmBgYAoKCgo8YnIvPgo8YnIvPgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9NH0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogICNmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKG1lZGlhbl9mYWNpbmdfYW5nbGUgPSBtZWRpYW4oZmFjaW5nX2FuZ2xlX19yYWQpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9bWVkaWFuX2ZhY2luZ19hbmdsZSkpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCwxLjUpCnAyIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKG1lZGlhbl9mYWNpbmdfYW5nbGUgPSBtZWRpYW4oZmFjaW5nX2FuZ2xlX19yYWQpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9bWVkaWFuX2ZhY2luZ19hbmdsZSkpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCwxKQpwMyA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkIDwgKDM1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lIAogIHN1bW1hcmlzZShtZWRpYW5fZmFjaW5nX2FuZ2xlID0gbWVkaWFuKGZhY2luZ19hbmdsZV9fcmFkKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PW1lZGlhbl9mYWNpbmdfYW5nbGUpKSArCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICB5bGltKDAsMikKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMixwMyksCiAgICAgICAgICBsYWJlbHMgPSBjKCJBbGwgRnJhbWVzIiwiV2luZyBFeHRlbnNpb24gRnJhbWVzIiwiTm9uLVdpbmcgRXh0ZW5zaW9uIEZyYW1lcyIpLAogICAgICAgICAgI2hqdXN0ID0gMSwKICAgICAgICAgIG5jb2wgPSAzLAogICAgICAgICAgbnJvdyA9IDEpCgpgYGAKCgoKPGJyLz4KPGJyLz4KCgoKYGBge3J9CnRlc3Rfc3RhdF90aWJibGUwIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICAjZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDM1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lIAogIHN1bW1hcmlzZShtZWRpYW5fZmFjaW5nX2FuZ2xlID0gbWVkaWFuKGZhY2luZ19hbmdsZV9fcmFkKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKQpgYGAKCmBgYHtyfQphb3YwIDwtIGFvdihtZWRpYW5fZmFjaW5nX2FuZ2xlfmdlbm90eXBlLGRhdGEgPSB0ZXN0X3N0YXRfdGliYmxlMCkKc3VtbWFyeShhb3YwKQpgYGAKCmBgYHtyfQpUdWtleUhTRChhb3YwKQpgYGAKCgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCgojIyMgKiptZWRpYW4gZmFjaW5nIGFuZ2xlIGJ5IHNlY3RvcioqCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTh9CnAxIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZmFjaW5nX2FuZ2xlX19yYWQgPCBwaS82KSAlPiUgCiAgI2ZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UobWVkaWFuX2ZhY2luZ19hbmdsZSA9IG1lZGlhbihmYWNpbmdfYW5nbGVfX3JhZCksCiAgICAgICAgICAgIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSwgeT1tZWRpYW5fZmFjaW5nX2FuZ2xlKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgeWxpbSgwLHBpLzYpCnAyIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZmFjaW5nX2FuZ2xlX19yYWQgPCBwaS82KSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDM1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lIAogIHN1bW1hcmlzZShtZWRpYW5fZmFjaW5nX2FuZ2xlID0gbWVkaWFuKGZhY2luZ19hbmdsZV9fcmFkKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PW1lZGlhbl9mYWNpbmdfYW5nbGUpKSArCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICB5bGltKDAscGkvNikKcDMgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA8IHBpLzYpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPCAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKG1lZGlhbl9mYWNpbmdfYW5nbGUgPSBtZWRpYW4oZmFjaW5nX2FuZ2xlX19yYWQpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9bWVkaWFuX2ZhY2luZ19hbmdsZSkpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCxwaS82KQpwNCA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkID4gcGkvNikgJT4lIAogICNmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKG1lZGlhbl9mYWNpbmdfYW5nbGUgPSBtZWRpYW4oZmFjaW5nX2FuZ2xlX19yYWQpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9bWVkaWFuX2ZhY2luZ19hbmdsZSkpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCxwaSkKcDUgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA+IHBpLzYpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKG1lZGlhbl9mYWNpbmdfYW5nbGUgPSBtZWRpYW4oZmFjaW5nX2FuZ2xlX19yYWQpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9bWVkaWFuX2ZhY2luZ19hbmdsZSkpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCxwaSkKcDYgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA+IHBpLzYpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPCAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKG1lZGlhbl9mYWNpbmdfYW5nbGUgPSBtZWRpYW4oZmFjaW5nX2FuZ2xlX19yYWQpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9bWVkaWFuX2ZhY2luZ19hbmdsZSkpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCxwaSkKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMixwMyxwNCxwNSxwNiksCiAgICAgICAgICBsYWJlbHMgPSBjKCJBbGwgRnJhbWVzIiwiV2luZyBFeHRlbnNpb24gRnJhbWVzIiwiTm9uLVdpbmcgRXh0ZW5zaW9uIEZyYW1lcyIpLAogICAgICAgICAgI2hqdXN0ID0gMSwKICAgICAgICAgIG5jb2wgPSAzLAogICAgICAgICAgbnJvdyA9IDIpCgpgYGAKCgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCiMjIyAqKm1lYW4gZmFjaW5nIGFuZ2xlIGJ5IHNlY3RvcioqCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9OH0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA8IHBpLzYpICU+JSAKICAjZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDM1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX2ZhY2luZ19hbmdsZSA9IG1lYW4oZmFjaW5nX2FuZ2xlX19yYWQpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9bWVhbl9mYWNpbmdfYW5nbGUpKSArCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICB5bGltKDAscGkvNikKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA8IHBpLzYpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fZmFjaW5nX2FuZ2xlID0gbWVhbihmYWNpbmdfYW5nbGVfX3JhZCksCiAgICAgICAgICAgIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSwgeT1tZWFuX2ZhY2luZ19hbmdsZSkpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCxwaS82KQpwMyA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkIDwgcGkvNikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA8ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9mYWNpbmdfYW5nbGUgPSBtZWFuKGZhY2luZ19hbmdsZV9fcmFkKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PW1lYW5fZmFjaW5nX2FuZ2xlKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgeWxpbSgwLHBpLzYpCnA0IDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZmFjaW5nX2FuZ2xlX19yYWQgPiBwaS82KSAlPiUgCiAgI2ZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9mYWNpbmdfYW5nbGUgPSBtZWFuKGZhY2luZ19hbmdsZV9fcmFkKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PW1lYW5fZmFjaW5nX2FuZ2xlKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgeWxpbSgwLHBpKQpwNSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkID4gcGkvNikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9mYWNpbmdfYW5nbGUgPSBtZWFuKGZhY2luZ19hbmdsZV9fcmFkKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PW1lYW5fZmFjaW5nX2FuZ2xlKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgeWxpbSgwLHBpKQpwNiA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkID4gcGkvNikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA8ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9mYWNpbmdfYW5nbGUgPSBtZWFuKGZhY2luZ19hbmdsZV9fcmFkKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PW1lYW5fZmFjaW5nX2FuZ2xlKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgeWxpbSgwLHBpKQpnZ2FycmFuZ2UocGxvdGxpc3QgPSBsaXN0KHAxLHAyLHAzLHA0LHA1LHA2KSwKICAgICAgICAgIGxhYmVscyA9IGMoIkFsbCBGcmFtZXMiLCJXaW5nIEV4dGVuc2lvbiBGcmFtZXMiLCJOb24tV2luZyBFeHRlbnNpb24gRnJhbWVzIiksCiAgICAgICAgICAjaGp1c3QgPSAxLAogICAgICAgICAgbmNvbCA9IDMsCiAgICAgICAgICBucm93ID0gMikKCmBgYAoKCgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCgojIyMgKiptZWFuIGZhY2luZyBhbmdsZSBieSB3ZWUgc2VjdG9ycyoqCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9OH0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA+IDApICU+JSAKICBmaWx0ZXIoZmFjaW5nX2FuZ2xlX19yYWQgPD0gcGkvNikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9mYWNpbmdfYW5nbGUgPSBtZWFuKGZhY2luZ19hbmdsZV9fcmFkKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PW1lYW5fZmFjaW5nX2FuZ2xlKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgIysKICAgICN5bGltKDAscGkvNikKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA+IHBpLzYpICU+JSAKICBmaWx0ZXIoZmFjaW5nX2FuZ2xlX19yYWQgPD0gMipwaS82KSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDM1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX2ZhY2luZ19hbmdsZSA9IG1lYW4oZmFjaW5nX2FuZ2xlX19yYWQpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9bWVhbl9mYWNpbmdfYW5nbGUpKSArCiAgICBnZW9tX2JveHBsb3QoKSAjKwogICAgI3lsaW0oMCxwaS82KQpwMyA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkID4gMipwaS82KSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkIDw9IDMqcGkvNikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA8ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9mYWNpbmdfYW5nbGUgPSBtZWFuKGZhY2luZ19hbmdsZV9fcmFkKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PW1lYW5fZmFjaW5nX2FuZ2xlKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgIysKICAgICN5bGltKDAscGkvNikKcDQgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA+IDMqcGkvNikgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA8PSA0KnBpLzYpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fZmFjaW5nX2FuZ2xlID0gbWVhbihmYWNpbmdfYW5nbGVfX3JhZCksCiAgICAgICAgICAgIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSwgeT1tZWFuX2ZhY2luZ19hbmdsZSkpICsKICAgIGdlb21fYm94cGxvdCgpICMrCiAgICAjeWxpbSgwLHBpKQpwNSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkID4gNCpwaS82KSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkIDw9IDUqcGkvNikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9mYWNpbmdfYW5nbGUgPSBtZWFuKGZhY2luZ19hbmdsZV9fcmFkKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PW1lYW5fZmFjaW5nX2FuZ2xlKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgIysKICAgICN5bGltKDAscGkpCnA2IDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZmFjaW5nX2FuZ2xlX19yYWQgPiA1KnBpLzYpICU+JSAKICBmaWx0ZXIoZmFjaW5nX2FuZ2xlX19yYWQgPD0gNipwaS82KSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkIDwgKDM1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX2ZhY2luZ19hbmdsZSA9IG1lYW4oZmFjaW5nX2FuZ2xlX19yYWQpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9bWVhbl9mYWNpbmdfYW5nbGUpKSArCiAgICBnZW9tX2JveHBsb3QoKSAjKwogICAgI3lsaW0oMCxwaSkKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMixwMyxwNCxwNSxwNiksCiAgICAgICAgICBsYWJlbHMgPSBjKCIwLXBpLzYiLCJwaS82LTJwaS82IiwiMnBpLzYtM3BpLzYiLAogICAgICAgICAgICAgICAgICAgICAiM3BpLzYtNHBpLzYiLCI0cGkvNi01cGkvNiIsIjVwaS82LTZwaS82IiksCiAgICAgICAgICAjaGp1c3QgPSAxLAogICAgICAgICAgbmNvbCA9IDMsCiAgICAgICAgICBucm93ID0gMikKCmBgYAoKCgoKCgoKCjxici8+Cjxici8+CgoKPGJyLz4KPGJyLz4KCgoKCgoKIyMjICoqY291bnRzIGluIHdlZSBzZWN0b3JzKioKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD04fQpwMSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkID4gMCkgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA8PSBwaS82KSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDM1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lIAogIHN1bW1hcmlzZShjb3VudHMgPSBsZW5ndGgoRnJhbWUpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9Y291bnRzKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgIysKICAgICN5bGltKDAscGkvNikKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA+IHBpLzYpICU+JSAKICBmaWx0ZXIoZmFjaW5nX2FuZ2xlX19yYWQgPD0gMipwaS82KSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDM1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lIAogIHN1bW1hcmlzZShjb3VudHMgPSBsZW5ndGgoRnJhbWUpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9Y291bnRzKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgIysKICAgICN5bGltKDAscGkvNikKcDMgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA+IDIqcGkvNikgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA8PSAzKnBpLzYpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPCAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50cyA9IGxlbmd0aChGcmFtZSksCiAgICAgICAgICAgIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSwgeT1jb3VudHMpKSArCiAgICBnZW9tX2JveHBsb3QoKSAjKwogICAgI3lsaW0oMCxwaS82KQpwNCA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkID4gMypwaS82KSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkIDw9IDQqcGkvNikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UoY291bnRzID0gbGVuZ3RoKEZyYW1lKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PWNvdW50cykpICsKICAgIGdlb21fYm94cGxvdCgpICMrCiAgICAjeWxpbSgwLHBpKQpwNSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkID4gNCpwaS82KSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkIDw9IDUqcGkvNikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UoY291bnRzID0gbGVuZ3RoKEZyYW1lKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PWNvdW50cykpICsKICAgIGdlb21fYm94cGxvdCgpICMrCiAgICAjeWxpbSgwLHBpKQpwNiA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkID4gNSpwaS82KSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkIDw9IDYqcGkvNikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA8ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UoY291bnRzID0gbGVuZ3RoKEZyYW1lKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PWNvdW50cykpICsKICAgIGdlb21fYm94cGxvdCgpICMrCiAgICAjeWxpbSgwLHBpKQpnZ2FycmFuZ2UocGxvdGxpc3QgPSBsaXN0KHAxLHAyLHAzLHA0LHA1LHA2KSwKICAgICAgICAgIGxhYmVscyA9IGMoIjAtcGkvNiIsInBpLzYtMnBpLzYiLCIycGkvNi0zcGkvNiIsCiAgICAgICAgICAgICAgICAgICAgICIzcGkvNi00cGkvNiIsIjRwaS82LTVwaS82IiwiNXBpLzYtNnBpLzYiKSwKICAgICAgICAgICNoanVzdCA9IDEsCiAgICAgICAgICBuY29sID0gMywKICAgICAgICAgIG5yb3cgPSAyKQoKYGBgCgoKCgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCiMjIyMgKipUb3RhbCB0aW1lIGluIHNlY3RvcioqCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTh9CnAxIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZmFjaW5nX2FuZ2xlX19yYWQgPiAwKSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkIDw9IHBpLzgpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50cyA9IGxlbmd0aChGcmFtZSksCiAgICAgICAgICAgIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSwgeT1jb3VudHMpKSArCiAgICBnZW9tX2JveHBsb3QoKSAjKwogICAgI3lsaW0oMCxwaS82KQpwMiA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkID4gcGkvOCkgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UoY291bnRzID0gbGVuZ3RoKEZyYW1lKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PWNvdW50cykpICsKICAgIGdlb21fYm94cGxvdCgpICMrCiAgICAjeWxpbSgwLHBpLzYpCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIpLAogICAgICAgICAgbGFiZWxzID0gYygiPHBpLzgiLCI+cGkvOCIpLAogICAgICAgICAgaGp1c3QgPSAtMC42LAogICAgICAgICAgdmp1c3QgPSAyLAogICAgICAgICAgbmNvbCA9IDIsCiAgICAgICAgICBucm93ID0gMSkKCmBgYAoKCgo8YnIvPgo8YnIvPgoKCjxici8+Cjxici8+CgoKIyMjIyAqKlByb3BvcnRpb24gdGltZSBpbiBzZWN0b3IqKgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTh9CnAxIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50cyA9IDEwMCpzdW0oZmFjaW5nX2FuZ2xlX19yYWQgPD0gcGkvOCkvbGVuZ3RoKEZyYW1lKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PWNvdW50cykpICsKICAgIGdlb21fYm94cGxvdCgpICMrCiAgICAjeWxpbSgwLHBpLzYpCnAyIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50cyA9IDEwMCpzdW0oZmFjaW5nX2FuZ2xlX19yYWQgPiBwaS84KS9sZW5ndGgoRnJhbWUpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9Y291bnRzKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgIysKICAgICN5bGltKDAscGkvNikKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMiksCiAgICAgICAgICBsYWJlbHMgPSBjKCI8cGkvOCIsIj5waS84IiksCiAgICAgICAgICBoanVzdCA9IC0xLjQsCiAgICAgICAgICB2anVzdCA9IDIsCiAgICAgICAgICBuY29sID0gMiwKICAgICAgICAgIG5yb3cgPSAxKQoKYGBgCgoKPGJyLz4KPGJyLz4KCgpgYGB7cn0KdGVzdF9zdGF0X3RpYmJsZTAgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIHN1bW1hcmlzZShjb3VudHMgPSAxMDAqc3VtKGZhY2luZ19hbmdsZV9fcmFkID4gcGkvOCkvbGVuZ3RoKEZyYW1lKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKQphb3YwIDwtIGFvdihjb3VudHN+Z2Vub3R5cGUsZGF0YSA9IHRlc3Rfc3RhdF90aWJibGUwKQojc3VtbWFyeShhb3YwKQpUdWtleUhTRChhb3YwKQpgYGAKCgoKPGJyLz4KPGJyLz4KCgoKYGBge3J9CnBhaXJ3aXNlLnQudGVzdCh0ZXN0X3N0YXRfdGliYmxlMCRjb3VudHMsIHRlc3Rfc3RhdF90aWJibGUwJGdlbm90eXBlKQpgYGAKCgoKCgoKCgoKCgoKCjxici8+Cjxici8+CgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTEyfQpwMSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkEiKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWZhY2luZ19hbmdsZV9fcmFkLCB5PWRpc3RfdG9fb3RoZXJfX21tKSkgKwogIGdlb21fYmluMmQoYmlucyA9IGMoMjAwLDUwKSkgKwogIHhsaW0oMCwyKnBpKSArCiAgeWxpbSgwLDIwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMiwyMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICBjb29yZF9wb2xhcigpICsKICB0aGVtZV92b2lkKCkKCnAyIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIGZpbHRlcihnZW5vdHlwZSA9PSAiQiIpICU+JSAKICBnZ3Bsb3QoYWVzKHg9ZmFjaW5nX2FuZ2xlX19yYWQsIHk9ZGlzdF90b19vdGhlcl9fbW0pKSArCiAgZ2VvbV9iaW4yZChiaW5zID0gYygyMDAsNTApKSArCiAgeGxpbSgwLDIqcGkpICsKICB5bGltKDAsMjApICsgCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIsbGltaXRzID0gYygyLDIwMDApLG5hLnZhbHVlID0gIndoaXRlIikgKwogIGNvb3JkX3BvbGFyKCkgKwogIHRoZW1lX3ZvaWQoKQoKcDMgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgZmlsdGVyKGdlbm90eXBlID09ICJDIikgJT4lIAogIGdncGxvdChhZXMoeD1mYWNpbmdfYW5nbGVfX3JhZCwgeT1kaXN0X3RvX290aGVyX19tbSkpICsKICBnZW9tX2JpbjJkKGJpbnMgPSBjKDIwMCw1MCkpICsKICB4bGltKDAsMipwaSkgKwogIHlsaW0oMCwyMCkgKyAKICBzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIixsaW1pdHMgPSBjKDIsMjAwMCksbmEudmFsdWUgPSAid2hpdGUiKSArCiAgY29vcmRfcG9sYXIoKSArCiAgdGhlbWVfdm9pZCgpCgpwNCA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkQiKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWZhY2luZ19hbmdsZV9fcmFkLCB5PWRpc3RfdG9fb3RoZXJfX21tKSkgKwogIGdlb21fYmluMmQoYmlucyA9IGMoMjAwLDUwKSkgKwogIHhsaW0oMCwyKnBpKSArCiAgeWxpbSgwLDIwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMiwyMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICBjb29yZF9wb2xhcigpICsKICB0aGVtZV92b2lkKCkKCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIscDMscDQpLAogICAgICAgICAgbGFiZWxzID0gYygiQSIsIkIiLCJDIiwiRCIpLAogICAgICAgICAgI2hqdXN0ID0gMSwKICAgICAgICAgIG5jb2wgPSAyLAogICAgICAgICAgbnJvdyA9IDIpCgpgYGAKCgo8YnIvPgo8YnIvPgoKCjxici8+Cjxici8+CgoKIyMjIyBUb3RhbCB0aW1lIGluIHNlY3RvcgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTh9CnAxIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA+IDApICU+JSAKICBmaWx0ZXIoZmFjaW5nX2FuZ2xlX19yYWQgPD0gcGkvOCkgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UoY291bnRzID0gbGVuZ3RoKEZyYW1lKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PWNvdW50cykpICsKICAgIGdlb21fYm94cGxvdCgpICMrCiAgICAjeWxpbSgwLHBpLzYpCnAyIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA+IHBpLzgpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50cyA9IGxlbmd0aChGcmFtZSksCiAgICAgICAgICAgIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSwgeT1jb3VudHMpKSArCiAgICBnZW9tX2JveHBsb3QoKSAjKwogICAgI3lsaW0oMCxwaS82KQpnZ2FycmFuZ2UocGxvdGxpc3QgPSBsaXN0KHAxLHAyKSwKICAgICAgICAgIGxhYmVscyA9IGMoIjxwaS84IiwiPnBpLzgiKSwKICAgICAgICAgIGhqdXN0ID0gLTAuNiwKICAgICAgICAgIHZqdXN0ID0gMiwKICAgICAgICAgIG5jb2wgPSAyLAogICAgICAgICAgbnJvdyA9IDEpCgpgYGAKCgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCiMjIyMgUHJvcG9ydGlvbiB0aW1lIGluIHNlY3RvciBhbmQgd2l0aGluIDEwbW0KCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD04fQpwMSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tIDwgMTApICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50cyA9IDEwMCpzdW0oZmFjaW5nX2FuZ2xlX19yYWQgPD0gcGkvOCkvbGVuZ3RoKEZyYW1lKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PWNvdW50cykpICsKICAgIGdlb21fYm94cGxvdCgpICMrCiAgICAjeWxpbSgwLHBpLzYpCnAyIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICB1bml0ZSgiaW5kaXZpZHVhbCIsIEZpbGVOYW1lOklkLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGdyb3VwX2J5KGluZGl2aWR1YWwpICU+JSAKICBzdW1tYXJpc2UoY291bnRzID0gMTAwKnN1bShmYWNpbmdfYW5nbGVfX3JhZCA+IHBpLzgpL2xlbmd0aChGcmFtZSksCiAgICAgICAgICAgIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSwgeT1jb3VudHMpKSArCiAgICBnZW9tX2JveHBsb3QoKSAjKwogICAgI3lsaW0oMCxwaS82KQpnZ2FycmFuZ2UocGxvdGxpc3QgPSBsaXN0KHAxLHAyKSwKICAgICAgICAgIGxhYmVscyA9IGMoIjxwaS84IiwiPnBpLzgiKSwKICAgICAgICAgIGhqdXN0ID0gLTEuNCwKICAgICAgICAgIHZqdXN0ID0gMiwKICAgICAgICAgIG5jb2wgPSAyLAogICAgICAgICAgbnJvdyA9IDEpCgpgYGAKCgo8YnIvPgo8YnIvPgoKCgoKYGBge3J9CnRlc3Rfc3RhdF90aWJibGUwIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tIDwgMTApICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIHN1bW1hcmlzZShjb3VudHMgPSAxMDAqc3VtKGZhY2luZ19hbmdsZV9fcmFkID4gcGkvOCkvbGVuZ3RoKEZyYW1lKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKQphb3YwIDwtIGFvdihjb3VudHN+Z2Vub3R5cGUsZGF0YSA9IHRlc3Rfc3RhdF90aWJibGUwKQojc3VtbWFyeShhb3YwKQpUdWtleUhTRChhb3YwKQpgYGAKCjxici8+Cjxici8+CgoKYGBge3J9CnBhaXJ3aXNlLnQudGVzdCh0ZXN0X3N0YXRfdGliYmxlMCRjb3VudHMsIHRlc3Rfc3RhdF90aWJibGUwJGdlbm90eXBlKQpgYGAKCgo8YnIvPgo8YnIvPgoKCjxici8+Cjxici8+CgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9MTJ9CnAxIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tIDwgMTApICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgZmlsdGVyKGdlbm90eXBlID09ICJBIikgJT4lIAogIGdncGxvdChhZXMoeD1mYWNpbmdfYW5nbGVfX3JhZCwgeT1kaXN0X3RvX290aGVyX19tbSkpICsKICBnZW9tX2JpbjJkKGJpbnMgPSBjKDIwMCw1MCkpICsKICB4bGltKDAsMipwaSkgKwogIHlsaW0oMCwxMCkgKyAKICBzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIixsaW1pdHMgPSBjKDAsMjAwMCksbmEudmFsdWUgPSAid2hpdGUiKSArCiAgdGhlbWVfdm9pZCgpICsKICBjb29yZF9wb2xhcigpCgpwMiA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA8IDEwKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIGZpbHRlcihnZW5vdHlwZSA9PSAiQiIpICU+JSAKICBnZ3Bsb3QoYWVzKHg9ZmFjaW5nX2FuZ2xlX19yYWQsIHk9ZGlzdF90b19vdGhlcl9fbW0pKSArCiAgZ2VvbV9iaW4yZChiaW5zID0gYygyMDAsNTApKSArCiAgeGxpbSgwLDIqcGkpICsKICB5bGltKDAsMTApICsgCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIsbGltaXRzID0gYygwLDIwMDApLG5hLnZhbHVlID0gIndoaXRlIikgKwogIHRoZW1lX3ZvaWQoKSArCiAgY29vcmRfcG9sYXIoKQoKcDMgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkMiKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWZhY2luZ19hbmdsZV9fcmFkLCB5PWRpc3RfdG9fb3RoZXJfX21tKSkgKwogIGdlb21fYmluMmQoYmlucyA9IGMoMjAwLDUwKSkgKwogIHhsaW0oMCwyKnBpKSArCiAgeWxpbSgwLDEwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMCwyMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKCnA0IDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tIDwgMTApICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgZmlsdGVyKGdlbm90eXBlID09ICJEIikgJT4lIAogIGdncGxvdChhZXMoeD1mYWNpbmdfYW5nbGVfX3JhZCwgeT1kaXN0X3RvX290aGVyX19tbSkpICsKICBnZW9tX2JpbjJkKGJpbnMgPSBjKDIwMCw1MCkpICsKICB4bGltKDAsMipwaSkgKwogIHlsaW0oMCwxMCkgKyAKICBzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIixsaW1pdHMgPSBjKDAsMjAwMCksbmEudmFsdWUgPSAid2hpdGUiKSArCiAgdGhlbWVfdm9pZCgpICsKICBjb29yZF9wb2xhcigpCgpnZ2FycmFuZ2UocGxvdGxpc3QgPSBsaXN0KHAxLHAyLHAzLHA0KSwKICAgICAgICAgIGxhYmVscyA9IGMoIkEiLCJCIiwiQyIsIkQiKSwKICAgICAgICAgICNoanVzdCA9IDEsCiAgICAgICAgICBuY29sID0gMiwKICAgICAgICAgIG5yb3cgPSAyKQoKYGBgCgoKCjxici8+Cjxici8+CgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMn0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkEiKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWZhY2luZ19hbmdsZV9fcmFkLCB5PWRpc3RfdG9fb3RoZXJfX21tKSkgKwogIGdlb21fYmluMmQoYmlucyA9IGMoMjAwLDUwKSkgKwogIHhsaW0oMCwyKnBpKSArCiAgeWxpbSgwLDEwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoNCwyMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKCnAyIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tIDwgMTApICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgZmlsdGVyKGdlbm90eXBlID09ICJCIikgJT4lIAogIGdncGxvdChhZXMoeD1mYWNpbmdfYW5nbGVfX3JhZCwgeT1kaXN0X3RvX290aGVyX19tbSkpICsKICBnZW9tX2JpbjJkKGJpbnMgPSBjKDIwMCw1MCkpICsKICB4bGltKDAsMipwaSkgKwogIHlsaW0oMCwxMCkgKyAKICBzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIixsaW1pdHMgPSBjKDQsMjAwMCksbmEudmFsdWUgPSAid2hpdGUiKSArCiAgdGhlbWVfdm9pZCgpICsKICBjb29yZF9wb2xhcigpCgpwMyA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA8IDEwKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIGZpbHRlcihnZW5vdHlwZSA9PSAiQyIpICU+JSAKICBnZ3Bsb3QoYWVzKHg9ZmFjaW5nX2FuZ2xlX19yYWQsIHk9ZGlzdF90b19vdGhlcl9fbW0pKSArCiAgZ2VvbV9iaW4yZChiaW5zID0gYygyMDAsNTApKSArCiAgeGxpbSgwLDIqcGkpICsKICB5bGltKDAsMTApICsgCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIsbGltaXRzID0gYyg0LDIwMDApLG5hLnZhbHVlID0gIndoaXRlIikgKwogIHRoZW1lX3ZvaWQoKSArCiAgY29vcmRfcG9sYXIoKQoKcDQgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkQiKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWZhY2luZ19hbmdsZV9fcmFkLCB5PWRpc3RfdG9fb3RoZXJfX21tKSkgKwogIGdlb21fYmluMmQoYmlucyA9IGMoMjAwLDUwKSkgKwogIHhsaW0oMCwyKnBpKSArCiAgeWxpbSgwLDEwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoNCwyMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIscDMscDQpLAogICAgICAgICAgbGFiZWxzID0gYygiQSIsIkIiLCJDIiwiRCIpLAogICAgICAgICAgI2hqdXN0ID0gMSwKICAgICAgICAgIG5jb2wgPSAyLAogICAgICAgICAgbnJvdyA9IDIpCgpgYGAKCgo8YnIvPgo8YnIvPgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9MTJ9CnAxIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tIDwgMTApICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgZmlsdGVyKGdlbm90eXBlID09ICJBIikgJT4lIAogIGdncGxvdChhZXMoeD1mYWNpbmdfYW5nbGVfX3JhZCwgeT1kaXN0X3RvX290aGVyX19tbSkpICsKICBnZW9tX2JpbjJkKGJpbnMgPSBjKDQwLDEwKSkgKwogIHhsaW0oMCwyKnBpKSArCiAgeWxpbSgwLDEwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoNTAsNTAwMDApLG5hLnZhbHVlID0gIndoaXRlIikgKwogIHRoZW1lX3ZvaWQoKSArCiAgY29vcmRfcG9sYXIoKQoKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkIiKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWZhY2luZ19hbmdsZV9fcmFkLCB5PWRpc3RfdG9fb3RoZXJfX21tKSkgKwogIGdlb21fYmluMmQoYmlucyA9IGMoNDAsMTApKSArCiAgeGxpbSgwLDIqcGkpICsKICB5bGltKDAsMTApICsgCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIsbGltaXRzID0gYyg1MCw1MDAwMCksbmEudmFsdWUgPSAid2hpdGUiKSArCiAgdGhlbWVfdm9pZCgpICsKICBjb29yZF9wb2xhcigpCgpwMyA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA8IDEwKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIGZpbHRlcihnZW5vdHlwZSA9PSAiQyIpICU+JSAKICBnZ3Bsb3QoYWVzKHg9ZmFjaW5nX2FuZ2xlX19yYWQsIHk9ZGlzdF90b19vdGhlcl9fbW0pKSArCiAgZ2VvbV9iaW4yZChiaW5zID0gYyg0MCwxMCkpICsKICB4bGltKDAsMipwaSkgKwogIHlsaW0oMCwxMCkgKyAKICBzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIixsaW1pdHMgPSBjKDUwLDUwMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKCnA0IDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tIDwgMTApICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgZmlsdGVyKGdlbm90eXBlID09ICJEIikgJT4lIAogIGdncGxvdChhZXMoeD1mYWNpbmdfYW5nbGVfX3JhZCwgeT1kaXN0X3RvX290aGVyX19tbSkpICsKICBnZW9tX2JpbjJkKGJpbnMgPSBjKDQwLDEwKSkgKwogIHhsaW0oMCwyKnBpKSArCiAgeWxpbSgwLDEwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoNTAsNTAwMDApLG5hLnZhbHVlID0gIndoaXRlIikgKwogIHRoZW1lX3ZvaWQoKSArCiAgY29vcmRfcG9sYXIoKQoKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMixwMyxwNCksCiAgICAgICAgICBsYWJlbHMgPSBjKCJBIiwiQiIsIkMiLCJEIiksCiAgICAgICAgICAjaGp1c3QgPSAxLAogICAgICAgICAgbmNvbCA9IDIsCiAgICAgICAgICBucm93ID0gMikKCmBgYAoKCgoKCjxici8+Cjxici8+CgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9MTJ9CnAxIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tIDwgMTApICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgZmlsdGVyKGdlbm90eXBlID09ICJBIikgJT4lIAogIGdncGxvdChhZXMoeD1mYWNpbmdfYW5nbGVfX3JhZCwgeT1kaXN0X3RvX290aGVyX19tbSkpICsKICBnZW9tX2JpbjJkKGJpbnMgPSBjKDEwMCwyNSkpICsKICB4bGltKDAsMipwaSkgKwogIHlsaW0oMCwxMCkgKyAKICBzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIixsaW1pdHMgPSBjKDEwLDIwMDApLG5hLnZhbHVlID0gIndoaXRlIikgKwogIHRoZW1lX3ZvaWQoKSArCiAgY29vcmRfcG9sYXIoKQoKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkIiKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWZhY2luZ19hbmdsZV9fcmFkLCB5PWRpc3RfdG9fb3RoZXJfX21tKSkgKwogIGdlb21fYmluMmQoYmlucyA9IGMoMTAwLDI1KSkgKwogIHhsaW0oMCwyKnBpKSArCiAgeWxpbSgwLDEwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMTAsMjAwMCksbmEudmFsdWUgPSAid2hpdGUiKSArCiAgdGhlbWVfdm9pZCgpICsKICBjb29yZF9wb2xhcigpCgpwMyA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA8IDEwKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIGZpbHRlcihnZW5vdHlwZSA9PSAiQyIpICU+JSAKICBnZ3Bsb3QoYWVzKHg9ZmFjaW5nX2FuZ2xlX19yYWQsIHk9ZGlzdF90b19vdGhlcl9fbW0pKSArCiAgZ2VvbV9iaW4yZChiaW5zID0gYygxMDAsMjUpKSArCiAgeGxpbSgwLDIqcGkpICsKICB5bGltKDAsMTApICsgCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIsbGltaXRzID0gYygxMCwyMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKCnA0IDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tIDwgMTApICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgZmlsdGVyKGdlbm90eXBlID09ICJEIikgJT4lIAogIGdncGxvdChhZXMoeD1mYWNpbmdfYW5nbGVfX3JhZCwgeT1kaXN0X3RvX290aGVyX19tbSkpICsKICBnZW9tX2JpbjJkKGJpbnMgPSBjKDEwMCwyNSkpICsKICB4bGltKDAsMipwaSkgKwogIHlsaW0oMCwxMCkgKyAKICBzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIixsaW1pdHMgPSBjKDEwLDIwMDApLG5hLnZhbHVlID0gIndoaXRlIikgKwogIHRoZW1lX3ZvaWQoKSArCiAgY29vcmRfcG9sYXIoKQoKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMixwMyxwNCksCiAgICAgICAgICBsYWJlbHMgPSBjKCJBIiwiQiIsIkMiLCJEIiksCiAgICAgICAgICAjaGp1c3QgPSAxLAogICAgICAgICAgbmNvbCA9IDIsCiAgICAgICAgICBucm93ID0gMikKCmBgYAoKCgoKCgoKCgoKCgoKCgoKCgoKCjxici8+Cjxici8+CgoKCgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTEyfQpwMSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA8IDEwKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIGZpbHRlcihnZW5vdHlwZSA9PSAiQSIpICU+JSAKICBnZ3Bsb3QoYWVzKHg9ZmFjaW5nX2FuZ2xlX19yYWQsIHk9ZGlzdF90b19vdGhlcl9fbW0pKSArCiAgc3RhdF9kZW5zaXR5XzJkKGFlcyhmaWxsID0gLi5sZXZlbC4uKSwgZ2VvbSA9ICJwb2x5Z29uIiwgY29sb3VyPSJ3aGl0ZSIpICsKICB4bGltKDAsMipwaSkgKwogIHlsaW0oMCw2KSArIAogICNzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIixsaW1pdHMgPSBjKDIsMjAwMCksbmEudmFsdWUgPSAid2hpdGUiKSArCiAgdGhlbWVfZ3JleSgpICsKICBjb29yZF9wb2xhcigpCiAgCgpwMiA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA8IDEwKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIGZpbHRlcihnZW5vdHlwZSA9PSAiQiIpICU+JSAKICBnZ3Bsb3QoYWVzKHg9ZmFjaW5nX2FuZ2xlX19yYWQsIHk9ZGlzdF90b19vdGhlcl9fbW0pKSArCiAgc3RhdF9kZW5zaXR5XzJkKGFlcyhmaWxsID0gLi5sZXZlbC4uKSwgZ2VvbSA9ICJwb2x5Z29uIiwgY29sb3VyPSJ3aGl0ZSIpICsKICB4bGltKDAsMipwaSkgKwogIHlsaW0oMCw2KSArIAogICNzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIixsaW1pdHMgPSBjKDIsMjAwMCksbmEudmFsdWUgPSAid2hpdGUiKSArCiAgdGhlbWVfZ3JleSgpICsKICBjb29yZF9wb2xhcigpCgpwMyA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA8IDEwKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIGZpbHRlcihnZW5vdHlwZSA9PSAiQyIpICU+JSAKICBnZ3Bsb3QoYWVzKHg9ZmFjaW5nX2FuZ2xlX19yYWQsIHk9ZGlzdF90b19vdGhlcl9fbW0pKSArCiAgc3RhdF9kZW5zaXR5XzJkKGFlcyhmaWxsID0gLi5sZXZlbC4uKSwgZ2VvbSA9ICJwb2x5Z29uIiwgY29sb3VyPSJ3aGl0ZSIpICsKICB4bGltKDAsMipwaSkgKwogIHlsaW0oMCw2KSArIAogICNzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIixsaW1pdHMgPSBjKDIsMjAwMCksbmEudmFsdWUgPSAid2hpdGUiKSArCiAgdGhlbWVfZ3JleSgpICsKICBjb29yZF9wb2xhcigpCgpwNCA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA8IDEwKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIGZpbHRlcihnZW5vdHlwZSA9PSAiRCIpICU+JSAKICBnZ3Bsb3QoYWVzKHg9ZmFjaW5nX2FuZ2xlX19yYWQsIHk9ZGlzdF90b19vdGhlcl9fbW0pKSArCiAgc3RhdF9kZW5zaXR5XzJkKGFlcyhmaWxsID0gLi5sZXZlbC4uKSwgZ2VvbSA9ICJwb2x5Z29uIiwgY29sb3VyPSJ3aGl0ZSIpICsKICB4bGltKDAsMipwaSkgKwogIHlsaW0oMCw2KSArIAogICNzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIixsaW1pdHMgPSBjKDIsMjAwMCksbmEudmFsdWUgPSAid2hpdGUiKSArCiAgdGhlbWVfZ3JleSgpICsKICBjb29yZF9wb2xhcigpCgpnZ2FycmFuZ2UocGxvdGxpc3QgPSBsaXN0KHAxLHAyLHAzLHA0KSwKICAgICAgICAgIGxhYmVscyA9IGMoIkEiLCJCIiwiQyIsIkQiKSwKICAgICAgICAgICNoanVzdCA9IDEsCiAgICAgICAgICBuY29sID0gMiwKICAgICAgICAgIG5yb3cgPSAyKQoKYGBgCgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCiMjIyMgVG90YWwgY291bnQgaW4gaW5uZXIgcmluZwoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9Nn0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkIDw9IHBpLzgpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tIDw9IDMpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50cyA9IGxlbmd0aChGcmFtZSksCiAgICAgICAgICAgIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSwgeT1jb3VudHMpKSArCiAgICBnZW9tX2JveHBsb3QoKSAjKwogICAgI3lsaW0oMCxwaS82KQpwMiA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBmaWx0ZXIoZmFjaW5nX2FuZ2xlX19yYWQgPD0gcGkvOCkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDMpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPD0gMTApICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50cyA9IGxlbmd0aChGcmFtZSksCiAgICAgICAgICAgIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSwgeT1jb3VudHMpKSArCiAgICBnZW9tX2JveHBsb3QoKSAjKwogICAgI3lsaW0oMCxwaS82KQpnZ2FycmFuZ2UocGxvdGxpc3QgPSBsaXN0KHAxLHAyKSwKICAgICAgICAgIGxhYmVscyA9IGMoIjJtbS0zbW0iLCIzbW0tMTBtbSIpLAogICAgICAgICAgaGp1c3QgPSAtMC42LAogICAgICAgICAgdmp1c3QgPSAyLAogICAgICAgICAgbmNvbCA9IDIsCiAgICAgICAgICBucm93ID0gMSkKCmBgYAoKCgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCiMjIyMgUHJvcG9ydGlvbiBjb3VudCBpbiBpbm5lciByaW5nCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9Nn0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZmlsdGVyKGZhY2luZ19hbmdsZV9fcmFkIDw9IHBpLzgpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMjUqcGkvMTgwKSkgJT4lCiAgdW5pdGUoImluZGl2aWR1YWwiLCBGaWxlTmFtZTpJZCwgcmVtb3ZlID0gRkFMU0UpICU+JSAKICBncm91cF9ieShpbmRpdmlkdWFsKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50cyA9IDEwMCpzdW0oZGlzdF90b19vdGhlcl9fbW0gPiAyICYgZGlzdF90b19vdGhlcl9fbW0gPD0gMykvbGVuZ3RoKEZyYW1lKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLCB5PWNvdW50cykpICsKICAgIGdlb21fYm94cGxvdCgpICMrCiAgICAjeWxpbSgwLHBpLzYpCnAyIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGZpbHRlcihmYWNpbmdfYW5nbGVfX3JhZCA8PSBwaS84KSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDI1KnBpLzE4MCkpICU+JQogIHVuaXRlKCJpbmRpdmlkdWFsIiwgRmlsZU5hbWU6SWQsIHJlbW92ZSA9IEZBTFNFKSAlPiUgCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lIAogIHN1bW1hcmlzZShjb3VudHMgPSAxMDAqc3VtKGRpc3RfdG9fb3RoZXJfX21tID4gMyAmIGRpc3RfdG9fb3RoZXJfX21tIDw9IDEwKS9sZW5ndGgoRnJhbWUpLAogICAgICAgICAgICBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUsIHk9Y291bnRzKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgIysKICAgICN5bGltKDAscGkvNikKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMiksCiAgICAgICAgICBsYWJlbHMgPSBjKCIybW0tM21tIiwiM21tLTEwbW0iKSwKICAgICAgICAgIGhqdXN0ID0gLTAuNiwKICAgICAgICAgIHZqdXN0ID0gMiwKICAgICAgICAgIG5jb2wgPSAyLAogICAgICAgICAgbnJvdyA9IDEpCgpgYGAKCgoKCjxici8+Cjxici8+CgoKYGBge3J9CnRlc3Rfc3RhdF90aWJibGUwIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBmaWx0ZXIoZmFjaW5nX2FuZ2xlX19yYWQgPD0gcGkvOCkgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICBncm91cF9ieSh1bmlxdWVfZmx5KSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50cyA9IDEwMCpzdW0oZGlzdF90b19vdGhlcl9fbW0gPiAyICYgZGlzdF90b19vdGhlcl9fbW0gPD0gMykvbGVuZ3RoKEZyYW1lKSwKICAgICAgICAgICAgZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpKQphb3YwIDwtIGFvdihjb3VudHN+Z2Vub3R5cGUsZGF0YSA9IHRlc3Rfc3RhdF90aWJibGUwKQojc3VtbWFyeShhb3YwKQpUdWtleUhTRChhb3YwKQpgYGAKCgoKCgoKCgoKCgoKCgoKCgo8YnIvPgo8YnIvPgoKCjxici8+Cjxici8+CgoKPGJyLz4KPGJyLz4KCgoKCiMgTGVmdCB2cyBSaWdodCB3aW5nCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD00fQpwMSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBncm91cF9ieSh1bmlxdWVfZmx5KSAlPiUgCiAgc3VtbWFyaXNlKGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSwKICAgICAgICAgICAgd2luZ19pbmRleCA9IDEwMCpzdW0oV2luZ0dlc3R1cmVbd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPD0gKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSo2MDApKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqNjAwKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLwogICAgICAgICAgICAgIGxlbmd0aChGcmFtZVt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqNjAwKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSo2MDApKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgICAgICAgICkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUseT13aW5nX2luZGV4KSkgKwogICAgZ2VvbV9ib3hwbG90KCkKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIHN1bW1hcmlzZShnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksCiAgICAgICAgICAgIHdpbmdfaW5kZXggPSAxMDAqc3VtKG1heF93aW5nX2FuZ19fcmFkW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSo2MDApKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqNjAwKSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0+KDM1KnBpLzE4MCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hLnJtID0gVFJVRSkvCiAgICAgICAgICAgICAgbGVuZ3RoKEZyYW1lW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSo2MDApKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqNjAwKSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgICAgICAgKSkgJT4lCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9d2luZ19pbmRleCkpICsKICAgIGdlb21fYm94cGxvdCgpCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIpLAogICAgICAgICAgbGFiZWxzID0gYygiSkFBQkEiLCJ3aW5nIGFuZ2xlIiksCiAgICAgICAgICBoanVzdCA9IC0wLjYsCiAgICAgICAgICB2anVzdCA9IDIsCiAgICAgICAgICBuY29sID0gMiwKICAgICAgICAgIG5yb3cgPSAxKQoKYGBgCgoKCgo8YnIvPgo8YnIvPgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTh9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBzdW1tYXJpc2UoZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpLAogICAgICAgICAgICBXaW5nX2luZGV4X2J5X0pBQUJBID0gMTAwKnN1bShXaW5nR2VzdHVyZVt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqNjAwKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkvCiAgICAgICAgICAgICAgbGVuZ3RoKEZyYW1lW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSo2MDApKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgV2luZ19pbmRleF9ieV9hbmdsZSA9IDEwMCpzdW0obWF4X3dpbmdfYW5nX19yYWRbd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPD0gKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXT4oMzUqcGkvMTgwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBUUlVFKS8KICAgICAgICAgICAgICBsZW5ndGgoRnJhbWVbd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPD0gKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgICAgICAgICApKSAlPiUKICBnZ3Bsb3QoYWVzKHg9V2luZ19pbmRleF9ieV9hbmdsZSx5PVdpbmdfaW5kZXhfYnlfSkFBQkEsY29sb3VyPWdlbm90eXBlKSkgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIGdlb21fc21vb3RoKG1ldGhvZD1sbSkgKwogICAgc3RhdF9jb3IobGFiZWwueSA9IGMoNTIsNTYsNjAsNjQpLCBzaXplID01KSArCiAgICBzdGF0X3JlZ2xpbmVfZXF1YXRpb24obGFiZWwueSA9IGMoNTAsNTQsNTgsNjIpLCBzaXplID01KSArCiAgICBjb29yZF9maXhlZCgpCmBgYAoKCgoKCgoKPGJyLz4KPGJyLz4KCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0xMH0Kd2luZCA8LSA2MDAKcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIHN1bW1hcmlzZShnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksCiAgICAgICAgICAgIHdpbmdfaW5kZXggPSAxMDAqc3VtKG1heF93aW5nX2FuZ19fcmFkW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdPigzNSpwaS8xODApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYS5ybSA9IFRSVUUpLwogICAgICAgICAgICAgIGxlbmd0aChGcmFtZVt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgICAgICAgICApKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9d2luZ19pbmRleCkpICsKICAgIGdlb21fYm94cGxvdCgpCnAyIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBzdW1tYXJpc2UoZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpLAogICAgICAgICAgICBsZWZ0X3dpbmdfaW5kZXggPSAxMDAqc3VtKHdpbmdfbF9hbmdfX3JhZFt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXTwoLTM1KnBpLzE4MCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hLnJtID0gVFJVRSkvCiAgICAgICAgICAgICAgbGVuZ3RoKEZyYW1lW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgICAgICAgICkpICU+JQogIGdncGxvdChhZXMoeD1nZW5vdHlwZSx5PWxlZnRfd2luZ19pbmRleCkpICsKICAgIGdlb21fYm94cGxvdCgpCnAzIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBzdW1tYXJpc2UoZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpLAogICAgICAgICAgICByaWdodF93aW5nX2luZGV4ID0gMTAwKnN1bSh3aW5nX3JfYW5nX19yYWRbd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPD0gKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0+KDM1KnBpLzE4MCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hLnJtID0gVFJVRSkvCiAgICAgICAgICAgICAgbGVuZ3RoKEZyYW1lW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgICAgICAgICkpICU+JQogIGdncGxvdChhZXMoeD1nZW5vdHlwZSx5PXJpZ2h0X3dpbmdfaW5kZXgpKSArCiAgICBnZW9tX2JveHBsb3QoKQpwNCA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBncm91cF9ieSh1bmlxdWVfZmx5KSAlPiUgCiAgc3VtbWFyaXNlKGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSwKICAgICAgICAgICAgYm90aF93aW5nX2luZGV4ID0gMTAwKnN1bShtaW5fd2luZ19hbmdfX3JhZFt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXT4oMzUqcGkvMTgwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBUUlVFKS8KICAgICAgICAgICAgICBsZW5ndGgoRnJhbWVbd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPD0gKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgICAgICAgKSkgJT4lCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9Ym90aF93aW5nX2luZGV4KSkgKwogICAgZ2VvbV9ib3hwbG90KCkKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwNCxwMixwMyksCiAgICAgICAgICBsYWJlbHMgPSBjKCJlaXRoZXIgd2luZyIsImJvdGggd2luZ3MiLCJsZWZ0IHdpbmciLCJyaWdodCB3aW5nIiksCiAgICAgICAgICBoanVzdCA9IC0wLjYsCiAgICAgICAgICB2anVzdCA9IDIsCiAgICAgICAgICBuY29sID0gMiwKICAgICAgICAgIG5yb3cgPSAyKQpgYGAKCgo8YnIvPgo8YnIvPgoKCgpgYGB7cn0KdGVzdF9zdGF0X3RpYmJsZSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgI2ZpbHRlcihnZW5vdHlwZSAhPSAiQSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBzdW1tYXJpc2UoZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpLAogICAgICAgICAgICBib3RoX3dpbmdfaW5kZXggPSAxMDAqc3VtKG1pbl93aW5nX2FuZ19fcmFkW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdPigzNSpwaS8xODApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYS5ybSA9IFRSVUUpLwogICAgICAgICAgICAgIGxlbmd0aChGcmFtZVt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgICAgICAgICApKQphb3YxIDwtIGFvdihib3RoX3dpbmdfaW5kZXh+Z2Vub3R5cGUsIGRhdGEgPSB0ZXN0X3N0YXRfdGliYmxlKQpUdWtleUhTRChhb3YxKQpgYGAKCgo8YnIvPgo8YnIvPgoKCjxici8+Cjxici8+CgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQp3aW5kIDwtIDYwMApwMSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBncm91cF9ieSh1bmlxdWVfZmx5KSAlPiUgCiAgc3VtbWFyaXNlKGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSwKICAgICAgICAgICAgYm90aF93aW5nX2luZGV4ID0gMTAwKnN1bShtaW5fd2luZ19hbmdfX3JhZFt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXT4oMTAqcGkvMTgwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBUUlVFKS8KICAgICAgICAgICAgICBsZW5ndGgoRnJhbWVbd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPD0gKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgICAgICAgKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSx5PWJvdGhfd2luZ19pbmRleCkpICsKICAgIGdlb21fYm94cGxvdCgpCnAyIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBzdW1tYXJpc2UoZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpLAogICAgICAgICAgICBib3RoX3dpbmdfaW5kZXggPSAxMDAqc3VtKG1pbl93aW5nX2FuZ19fcmFkW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdPigyMCpwaS8xODApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYS5ybSA9IFRSVUUpLwogICAgICAgICAgICAgIGxlbmd0aChGcmFtZVt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgICAgICAgICApKSAlPiUKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUseT1ib3RoX3dpbmdfaW5kZXgpKSArCiAgICBnZW9tX2JveHBsb3QoKQpwMyA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBncm91cF9ieSh1bmlxdWVfZmx5KSAlPiUgCiAgc3VtbWFyaXNlKGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSwKICAgICAgICAgICAgYm90aF93aW5nX2luZGV4ID0gMTAwKnN1bShtaW5fd2luZ19hbmdfX3JhZFt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXT4oMzAqcGkvMTgwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBUUlVFKS8KICAgICAgICAgICAgICBsZW5ndGgoRnJhbWVbd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPD0gKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgICAgICAgKSkgJT4lCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9Ym90aF93aW5nX2luZGV4KSkgKwogICAgZ2VvbV9ib3hwbG90KCkKcDQgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIHN1bW1hcmlzZShnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksCiAgICAgICAgICAgIGJvdGhfd2luZ19pbmRleCA9IDEwMCpzdW0obWluX3dpbmdfYW5nX19yYWRbd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPD0gKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0+KDQwKnBpLzE4MCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hLnJtID0gVFJVRSkvCiAgICAgICAgICAgICAgbGVuZ3RoKEZyYW1lW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgICAgICAgICkpICU+JQogIGdncGxvdChhZXMoeD1nZW5vdHlwZSx5PWJvdGhfd2luZ19pbmRleCkpICsKICAgIGdlb21fYm94cGxvdCgpCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIscDMscDQpLAogICAgICAgICAgbGFiZWxzID0gYygiPjEwZGVnIiwiPjIwZGVnIiwiPjMwZGVnIiwiPjQwZGVnIiksCiAgICAgICAgICBoanVzdCA9IC0wLjYsCiAgICAgICAgICB2anVzdCA9IDIsCiAgICAgICAgICBuY29sID0gNCwKICAgICAgICAgIG5yb3cgPSAxKQpgYGAKCgo8YnIvPgo8YnIvPgoKCgoKCgoKCgo8YnIvPgo8YnIvPgoKCgpgYGB7cn0KdGVzdF9zdGF0X3RpYmJsZSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgI2ZpbHRlcihnZW5vdHlwZSAhPSAiQSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBzdW1tYXJpc2UoZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpLAogICAgICAgICAgICBib3RoX3dpbmdfaW5kZXggPSAxMDAqc3VtKG1pbl93aW5nX2FuZ19fcmFkW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdPigxNSpwaS8xODApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYS5ybSA9IFRSVUUpLwogICAgICAgICAgICAgIGxlbmd0aChGcmFtZVt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgICAgICAgICApKQphb3YxIDwtIGFvdihib3RoX3dpbmdfaW5kZXh+Z2Vub3R5cGUsIGRhdGEgPSB0ZXN0X3N0YXRfdGliYmxlKQpUdWtleUhTRChhb3YxKQpgYGAKCgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0Kd2luZCA8LSA2MDAKcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIHN1bW1hcmlzZShnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksCiAgICAgICAgICAgIG1lYW5fbWF4X3dpbmcgPSBtZWFuKG1heF93aW5nX2FuZ19fcmFkW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKQogICAgICAgICAgICApICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUseT1tZWFuX21heF93aW5nKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgeWxpbSgwLDEuNSkKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIHN1bW1hcmlzZShnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksCiAgICAgICAgICAgIG1lYW5fbGVmdF93aW5nID0gLW1lYW4od2luZ19sX2FuZ19fcmFkW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLG5hLnJtID0gVFJVRSkKICAgICAgICAgICAgKSAlPiUKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUseT1tZWFuX2xlZnRfd2luZykpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCwxLjUpCnAzIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBzdW1tYXJpc2UoZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpLAogICAgICAgICAgICBtZWFuX3JpZ2h0X3dpbmcgPSBtZWFuKHdpbmdfcl9hbmdfX3JhZFt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXSxuYS5ybSA9IFRSVUUpCiAgICAgICAgICAgICkgJT4lCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9bWVhbl9yaWdodF93aW5nKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgeWxpbSgwLDEuNSkKcDQgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIHN1bW1hcmlzZShnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksCiAgICAgICAgICAgIG1lYW5fbWluX3dpbmcgPSBtZWFuKG1pbl93aW5nX2FuZ19fcmFkW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKQogICAgICAgICAgICApICU+JQogIGdncGxvdChhZXMoeD1nZW5vdHlwZSx5PW1lYW5fbWluX3dpbmcpKSArCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICB5bGltKDAsMS41KQpnZ2FycmFuZ2UocGxvdGxpc3QgPSBsaXN0KHAxLHA0LHAyLHAzKSwKICAgICAgICAgIGxhYmVscyA9IGMoIm1heCB3aW5nIiwibWluIHdpbmdzIiwibGVmdCB3aW5nIiwicmlnaHQgd2luZyIpLAogICAgICAgICAgaGp1c3QgPSAtMC42LAogICAgICAgICAgdmp1c3QgPSAyLAogICAgICAgICAgbmNvbCA9IDQsCiAgICAgICAgICBucm93ID0gMSkKYGBgCgoKCgoKCjxici8+Cjxici8+CgoKCmBgYHtyfQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBncm91cF9ieSh1bmlxdWVfZmx5KSAlPiUgCiAgc3VtbWFyaXNlKGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSwKICAgICAgICAgICAgbWVhbl9taW5fd2luZyA9IG1lYW4obWluX3dpbmdfYW5nX19yYWRbd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPD0gKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0pCiAgICAgICAgICAgICkgJT4lCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9bWVhbl9taW5fd2luZykpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCwuNSkKYGBgCgoKCgo8YnIvPgo8YnIvPgoKCgpgYGB7cn0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIHN1bW1hcmlzZShnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksCiAgICAgICAgICAgIG1pbl93aW5nX2d0XzE1ID0gc3VtKG1lYW4obWluX3dpbmdfYW5nX19yYWRbd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPD0gKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0pPjE1KnBpLzE4MCkKICAgICAgICAgICAgKSAlPiUgCiAgc3VtbWFyaXNlKHRvdF9taW5fd2luZ19ndF8xNSA9IHN1bShtaW5fd2luZ19ndF8xNT4wLG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIHByb3BfbWluX3dpbmdfZ3RfMTUgPSAxMDAqc3VtKG1pbl93aW5nX2d0XzE1PjAsbmEucm0gPSBUUlVFKS9sZW5ndGgobWluX3dpbmdfZ3RfMTUpKQpgYGAKCgoKCgoKCgoKCgo8YnIvPgo8YnIvPgoKCjxici8+Cjxici8+CgoKCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMn0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkEiKSAlPiUgCiAgZ2dwbG90KGFlcyh4PS13aW5nX2xfYW5nX19yYWQsIHk9d2luZ19sX2xlbl9fcHgpKSArCiAgZ2VvbV9iaW4yZChiaW5zID0gYygyMDAsNTApKSArCiAgeGxpbSgwLDIqcGkpICsKICB5bGltKDAsNDApICsgCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIsbGltaXRzID0gYygwLDEwMDApLG5hLnZhbHVlID0gIndoaXRlIikgKwogIHRoZW1lX3ZvaWQoKSArCiAgY29vcmRfcG9sYXIoKQoKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkIiKSAlPiUgCiAgZ2dwbG90KGFlcyh4PS13aW5nX2xfYW5nX19yYWQsIHk9d2luZ19sX2xlbl9fcHgpKSArCiAgZ2VvbV9iaW4yZChiaW5zID0gYygyMDAsNTApKSArCiAgeGxpbSgwLDIqcGkpICsKICB5bGltKDAsNDApICsgCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIsbGltaXRzID0gYygwLDEwMDApLG5hLnZhbHVlID0gIndoaXRlIikgKwogIHRoZW1lX3ZvaWQoKSArCiAgY29vcmRfcG9sYXIoKQoKcDMgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkMiKSAlPiUgCiAgZ2dwbG90KGFlcyh4PS13aW5nX2xfYW5nX19yYWQsIHk9d2luZ19sX2xlbl9fcHgpKSArCiAgZ2VvbV9iaW4yZChiaW5zID0gYygyMDAsNTApKSArCiAgeGxpbSgwLDIqcGkpICsKICB5bGltKDAsNDApICsgCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIsbGltaXRzID0gYygwLDEwMDApLG5hLnZhbHVlID0gIndoaXRlIikgKwogIHRoZW1lX3ZvaWQoKSArCiAgY29vcmRfcG9sYXIoKQoKcDQgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkQiKSAlPiUgCiAgZ2dwbG90KGFlcyh4PS13aW5nX2xfYW5nX19yYWQsIHk9d2luZ19sX2xlbl9fcHgpKSArCiAgZ2VvbV9iaW4yZChiaW5zID0gYygyMDAsNTApKSArCiAgeGxpbSgwLDIqcGkpICsKICB5bGltKDAsNDApICsgCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIsbGltaXRzID0gYygwLDEwMDApLG5hLnZhbHVlID0gIndoaXRlIikgKwogIHRoZW1lX3ZvaWQoKSArCiAgY29vcmRfcG9sYXIoKQoKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMixwMyxwNCksCiAgICAgICAgICBsYWJlbHMgPSBjKCJBIiwiQiIsIkMiLCJEIiksCiAgICAgICAgICAjaGp1c3QgPSAxLAogICAgICAgICAgbmNvbCA9IDIsCiAgICAgICAgICBucm93ID0gMikKCmBgYAoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9MTJ9CnAxIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tIDwgMTApICU+JSAKICBmaWx0ZXIobWluX3dpbmdfYW5nX19yYWQgPiAoMTUqcGkvMTgwKSkgJT4lCiAgZmlsdGVyKGdlbm90eXBlID09ICJBIikgJT4lIAogIGdncGxvdChhZXMoeD13aW5nX3JfYW5nX19yYWQsIHk9d2luZ19yX2xlbl9fcHgpKSArCiAgZ2VvbV9iaW4yZChiaW5zID0gYygyMDAsNTApKSArCiAgeGxpbSgwLDIqcGkpICsKICB5bGltKDAsNDApICsgCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIsbGltaXRzID0gYygwLDEwMDApLG5hLnZhbHVlID0gIndoaXRlIikgKwogIHRoZW1lX3ZvaWQoKSArCiAgY29vcmRfcG9sYXIoKQoKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkIiKSAlPiUgCiAgZ2dwbG90KGFlcyh4PXdpbmdfcl9hbmdfX3JhZCwgeT13aW5nX3JfbGVuX19weCkpICsKICBnZW9tX2JpbjJkKGJpbnMgPSBjKDIwMCw1MCkpICsKICB4bGltKDAsMipwaSkgKwogIHlsaW0oMCw0MCkgKyAKICBzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIixsaW1pdHMgPSBjKDAsMTAwMCksbmEudmFsdWUgPSAid2hpdGUiKSArCiAgdGhlbWVfdm9pZCgpICsKICBjb29yZF9wb2xhcigpCgpwMyA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA8IDEwKSAlPiUgCiAgZmlsdGVyKG1pbl93aW5nX2FuZ19fcmFkID4gKDE1KnBpLzE4MCkpICU+JQogIGZpbHRlcihnZW5vdHlwZSA9PSAiQyIpICU+JSAKICBnZ3Bsb3QoYWVzKHg9d2luZ19yX2FuZ19fcmFkLCB5PXdpbmdfcl9sZW5fX3B4KSkgKwogIGdlb21fYmluMmQoYmlucyA9IGMoMjAwLDUwKSkgKwogIHhsaW0oMCwyKnBpKSArCiAgeWxpbSgwLDQwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMCwxMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKCnA0IDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tIDwgMTApICU+JSAKICBmaWx0ZXIobWluX3dpbmdfYW5nX19yYWQgPiAoMTUqcGkvMTgwKSkgJT4lCiAgZmlsdGVyKGdlbm90eXBlID09ICJEIikgJT4lIAogIGdncGxvdChhZXMoeD13aW5nX3JfYW5nX19yYWQsIHk9d2luZ19yX2xlbl9fcHgpKSArCiAgZ2VvbV9iaW4yZChiaW5zID0gYygyMDAsNTApKSArCiAgeGxpbSgwLDIqcGkpICsKICB5bGltKDAsNDApICsgCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIsbGltaXRzID0gYygwLDEwMDApLG5hLnZhbHVlID0gIndoaXRlIikgKwogIHRoZW1lX3ZvaWQoKSArCiAgY29vcmRfcG9sYXIoKQoKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMixwMyxwNCksCiAgICAgICAgICBsYWJlbHMgPSBjKCJBIiwiQiIsIkMiLCJEIiksCiAgICAgICAgICAjaGp1c3QgPSAxLAogICAgICAgICAgbmNvbCA9IDIsCiAgICAgICAgICBucm93ID0gMikKCmBgYAoKCgoKCgoKCgoKCjxici8+Cjxici8+CgoKPGJyLz4KPGJyLz4KCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMn0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkEiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGdlb21fYmluMmQoYWVzKHg9d2luZ19yX2FuZ19fcmFkLCB5PXdpbmdfcl9sZW5fX3B4KSwgYmlucyA9IGMoMjAwLDUwKSkgKwogIGdlb21fYmluMmQoYWVzKHg9d2luZ19sX2FuZ19fcmFkLCB5PXdpbmdfbF9sZW5fX3B4KSwgYmlucyA9IGMoMjAwLDUwKSkgKwogIHhsaW0oLXBpLHBpKSArCiAgeWxpbSgwLDYwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMCwxMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkIiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGdlb21fYmluMmQoYWVzKHg9d2luZ19yX2FuZ19fcmFkLCB5PXdpbmdfcl9sZW5fX3B4KSwgYmlucyA9IGMoMjAwLDUwKSkgKwogIGdlb21fYmluMmQoYWVzKHg9d2luZ19sX2FuZ19fcmFkLCB5PXdpbmdfbF9sZW5fX3B4KSwgYmlucyA9IGMoMjAwLDUwKSkgKwogIHhsaW0oLXBpLHBpKSArCiAgeWxpbSgwLDYwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMCwxMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKcDMgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkMiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGdlb21fYmluMmQoYWVzKHg9d2luZ19yX2FuZ19fcmFkLCB5PXdpbmdfcl9sZW5fX3B4KSwgYmlucyA9IGMoMjAwLDUwKSkgKwogIGdlb21fYmluMmQoYWVzKHg9d2luZ19sX2FuZ19fcmFkLCB5PXdpbmdfbF9sZW5fX3B4KSwgYmlucyA9IGMoMjAwLDUwKSkgKwogIHhsaW0oLXBpLHBpKSArCiAgeWxpbSgwLDYwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMCwxMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKcDQgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkQiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGdlb21fYmluMmQoYWVzKHg9d2luZ19yX2FuZ19fcmFkLCB5PXdpbmdfcl9sZW5fX3B4KSwgYmlucyA9IGMoMjAwLDUwKSkgKwogIGdlb21fYmluMmQoYWVzKHg9d2luZ19sX2FuZ19fcmFkLCB5PXdpbmdfbF9sZW5fX3B4KSwgYmlucyA9IGMoMjAwLDUwKSkgKwogIHhsaW0oLXBpLHBpKSArCiAgeWxpbSgwLDYwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMCwxMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIscDMscDQpLAogICAgICAgICAgbGFiZWxzID0gYygiQSIsIkIiLCJDIiwiRCIpLAogICAgICAgICAgI2hqdXN0ID0gMSwKICAgICAgICAgIG5jb2wgPSAyLAogICAgICAgICAgbnJvdyA9IDIpCmBgYAoKCgoKCgoKCgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTEyfQpwMSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA8IDEwKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkIDwgKDIqcGkvMykpICU+JQogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgwKSkgJT4lCiAgZmlsdGVyKHdpbmdfbF9hbmdfX3JhZCA+ICgtMipwaS8zKSkgJT4lCiAgZmlsdGVyKHdpbmdfcl9hbmdfX3JhZCA8ICgyKnBpLzMpKSAlPiUKICBmaWx0ZXIod2luZ19sX2FuZ19fcmFkIDwgKDApKSAlPiUKICBmaWx0ZXIod2luZ19yX2FuZ19fcmFkID4gKDApKSAlPiUKICBmaWx0ZXIoZGlzdF90b193YWxsX19tbSA+IDIpICU+JQogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkEiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGdlb21fYmluMmQoYWVzKHg9d2luZ19yX2FuZ19fcmFkLCB5PXdpbmdfcl9sZW5fX3B4KSwgYmlucyA9IGMoMjAwLDUwKSkgKwogIGdlb21fYmluMmQoYWVzKHg9d2luZ19sX2FuZ19fcmFkLCB5PXdpbmdfbF9sZW5fX3B4KSwgYmlucyA9IGMoMjAwLDUwKSkgKwogIHhsaW0oLXBpLHBpKSArCiAgeWxpbSgwLDYwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMTAsNTAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA8ICgyKnBpLzMpKSAlPiUKICBmaWx0ZXIobWluX3dpbmdfYW5nX19yYWQgPiAoMCkpICU+JQogIGZpbHRlcih3aW5nX2xfYW5nX19yYWQgPiAoLTIqcGkvMykpICU+JQogIGZpbHRlcih3aW5nX3JfYW5nX19yYWQgPCAoMipwaS8zKSkgJT4lCiAgZmlsdGVyKHdpbmdfbF9hbmdfX3JhZCA8ICgwKSkgJT4lCiAgZmlsdGVyKHdpbmdfcl9hbmdfX3JhZCA+ICgwKSkgJT4lCiAgZmlsdGVyKGRpc3RfdG9fd2FsbF9fbW0gPiAyKSAlPiUKICBmaWx0ZXIobWluX3dpbmdfYW5nX19yYWQgPiAoMTUqcGkvMTgwKSkgJT4lCiAgZmlsdGVyKGdlbm90eXBlID09ICJCIikgJT4lIAogIGdncGxvdCgpICsKICBnZW9tX2JpbjJkKGFlcyh4PXdpbmdfcl9hbmdfX3JhZCwgeT13aW5nX3JfbGVuX19weCksIGJpbnMgPSBjKDIwMCw1MCkpICsKICBnZW9tX2JpbjJkKGFlcyh4PXdpbmdfbF9hbmdfX3JhZCwgeT13aW5nX2xfbGVuX19weCksIGJpbnMgPSBjKDIwMCw1MCkpICsKICB4bGltKC1waSxwaSkgKwogIHlsaW0oMCw2MCkgKyAKICBzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIixsaW1pdHMgPSBjKDEwLDUwMCksbmEudmFsdWUgPSAid2hpdGUiKSArCiAgdGhlbWVfdm9pZCgpICsKICBjb29yZF9wb2xhcigpCnAzIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tIDwgMTApICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPCAoMipwaS8zKSkgJT4lCiAgZmlsdGVyKG1pbl93aW5nX2FuZ19fcmFkID4gKDApKSAlPiUKICBmaWx0ZXIod2luZ19sX2FuZ19fcmFkID4gKC0yKnBpLzMpKSAlPiUKICBmaWx0ZXIod2luZ19yX2FuZ19fcmFkIDwgKDIqcGkvMykpICU+JQogIGZpbHRlcih3aW5nX2xfYW5nX19yYWQgPCAoMCkpICU+JQogIGZpbHRlcih3aW5nX3JfYW5nX19yYWQgPiAoMCkpICU+JQogIGZpbHRlcihkaXN0X3RvX3dhbGxfX21tID4gMikgJT4lCiAgZmlsdGVyKG1pbl93aW5nX2FuZ19fcmFkID4gKDE1KnBpLzE4MCkpICU+JQogIGZpbHRlcihnZW5vdHlwZSA9PSAiQyIpICU+JSAKICBnZ3Bsb3QoKSArCiAgZ2VvbV9iaW4yZChhZXMoeD13aW5nX3JfYW5nX19yYWQsIHk9d2luZ19yX2xlbl9fcHgpLCBiaW5zID0gYygyMDAsNTApKSArCiAgZ2VvbV9iaW4yZChhZXMoeD13aW5nX2xfYW5nX19yYWQsIHk9d2luZ19sX2xlbl9fcHgpLCBiaW5zID0gYygyMDAsNTApKSArCiAgeGxpbSgtcGkscGkpICsKICB5bGltKDAsNjApICsgCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIsbGltaXRzID0gYygxMCw1MDApLG5hLnZhbHVlID0gIndoaXRlIikgKwogIHRoZW1lX3ZvaWQoKSArCiAgY29vcmRfcG9sYXIoKQpwNCA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA8IDEwKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkIDwgKDIqcGkvMykpICU+JQogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgwKSkgJT4lCiAgZmlsdGVyKHdpbmdfbF9hbmdfX3JhZCA+ICgtMipwaS8zKSkgJT4lCiAgZmlsdGVyKHdpbmdfcl9hbmdfX3JhZCA8ICgyKnBpLzMpKSAlPiUKICBmaWx0ZXIod2luZ19sX2FuZ19fcmFkIDwgKDApKSAlPiUKICBmaWx0ZXIod2luZ19yX2FuZ19fcmFkID4gKDApKSAlPiUKICBmaWx0ZXIoZGlzdF90b193YWxsX19tbSA+IDIpICU+JQogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkQiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGdlb21fYmluMmQoYWVzKHg9d2luZ19yX2FuZ19fcmFkLCB5PXdpbmdfcl9sZW5fX3B4KSwgYmlucyA9IGMoMjAwLDUwKSkgKwogIGdlb21fYmluMmQoYWVzKHg9d2luZ19sX2FuZ19fcmFkLCB5PXdpbmdfbF9sZW5fX3B4KSwgYmlucyA9IGMoMjAwLDUwKSkgKwogIHhsaW0oLXBpLHBpKSArCiAgeWxpbSgwLDYwKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMTAsNTAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIscDMscDQpLAogICAgICAgICAgbGFiZWxzID0gYygiQSIsIkIiLCJDIiwiRCIpLAogICAgICAgICAgI2hqdXN0ID0gMSwKICAgICAgICAgIG5jb2wgPSAyLAogICAgICAgICAgbnJvdyA9IDIpCmBgYAoKCgoKCgoKCgoKCjxici8+Cjxici8+CgoKPGJyLz4KPGJyLz4KCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMn0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkEiKSAlPiUgCiAgZ2dwbG90KCkgKwogIHN0YXRfZGVuc2l0eV8yZChhZXMoeD13aW5nX3JfYW5nX19yYWQsIHk9d2luZ19yX2xlbl9fcHgsZmlsbCA9IC4ubGV2ZWwuLiksIGdlb20gPSAicG9seWdvbiIpICsKICBzdGF0X2RlbnNpdHlfMmQoYWVzKHg9d2luZ19sX2FuZ19fcmFkLCB5PXdpbmdfbF9sZW5fX3B4LGZpbGwgPSAuLmxldmVsLi4pLCBnZW9tID0gInBvbHlnb24iKSArCiAgeGxpbSgtcGkscGkpICsKICB5bGltKDAsNjApICsgCiAgI3NjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMCwxMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkIiKSAlPiUgCiAgZ2dwbG90KCkgKwogIHN0YXRfZGVuc2l0eV8yZChhZXMoeD13aW5nX3JfYW5nX19yYWQsIHk9d2luZ19yX2xlbl9fcHgsZmlsbCA9IC4ubGV2ZWwuLiksIGdlb20gPSAicG9seWdvbiIpICsKICBzdGF0X2RlbnNpdHlfMmQoYWVzKHg9d2luZ19sX2FuZ19fcmFkLCB5PXdpbmdfbF9sZW5fX3B4LGZpbGwgPSAuLmxldmVsLi4pLCBnZW9tID0gInBvbHlnb24iKSArCiAgeGxpbSgtcGkscGkpICsKICB5bGltKDAsNjApICsgCiAgI3NjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMCwxMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKcDMgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkMiKSAlPiUgCiAgZ2dwbG90KCkgKwogIHN0YXRfZGVuc2l0eV8yZChhZXMoeD13aW5nX3JfYW5nX19yYWQsIHk9d2luZ19yX2xlbl9fcHgsZmlsbCA9IC4ubGV2ZWwuLiksIGdlb20gPSAicG9seWdvbiIpICsKICBzdGF0X2RlbnNpdHlfMmQoYWVzKHg9d2luZ19sX2FuZ19fcmFkLCB5PXdpbmdfbF9sZW5fX3B4LGZpbGwgPSAuLmxldmVsLi4pLCBnZW9tID0gInBvbHlnb24iKSArCiAgeGxpbSgtcGkscGkpICsKICB5bGltKDAsNjApICsgCiAgI3NjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMCwxMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKcDQgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtaW5fd2luZ19hbmdfX3JhZCA+ICgxNSpwaS8xODApKSAlPiUKICBmaWx0ZXIoZ2Vub3R5cGUgPT0gIkQiKSAlPiUgCiAgZ2dwbG90KCkgKwogIHN0YXRfZGVuc2l0eV8yZChhZXMoeD13aW5nX3JfYW5nX19yYWQsIHk9d2luZ19yX2xlbl9fcHgsZmlsbCA9IC4ubGV2ZWwuLiksIGdlb20gPSAicG9seWdvbiIpICsKICBzdGF0X2RlbnNpdHlfMmQoYWVzKHg9d2luZ19sX2FuZ19fcmFkLCB5PXdpbmdfbF9sZW5fX3B4LGZpbGwgPSAuLmxldmVsLi4pLCBnZW9tID0gInBvbHlnb24iKSArCiAgeGxpbSgtcGkscGkpICsKICB5bGltKDAsNjApICsgCiAgI3NjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiLGxpbWl0cyA9IGMoMCwxMDAwKSxuYS52YWx1ZSA9ICJ3aGl0ZSIpICsKICB0aGVtZV92b2lkKCkgKwogIGNvb3JkX3BvbGFyKCkKCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIscDMscDQpLAogICAgICAgICAgbGFiZWxzID0gYygiQSIsIkIiLCJDIiwiRCIpLAogICAgICAgICAgI2hqdXN0ID0gMSwKICAgICAgICAgIG5jb2wgPSAyLAogICAgICAgICAgbnJvdyA9IDIpCmBgYAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo8YnIvPgo8YnIvPgoKCjxici8+Cjxici8+CgoKCgoKCgpgYGB7cn0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPCAxMCkgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgyNSpwaS8xODApKSAlPiUKICAjZmlsdGVyKGdlbm90eXBlID09ICJEIikgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSwgeT13aW5nX2xfbGVuX19weCkpKwogIGdlb21fYm94cGxvdCgpCmBgYAoKCgoKCjxici8+Cjxici8+CgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCiMgKipGYWNpbmcgYW5nbGUgYXQgc3RhcnQgdnMgZW5kIG9mIHdpbmcgYm91dCoqCgoKPGJyLz4KPGJyLz4KCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKEZpbGVOYW1lID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyMzRfMiIpICU+JSAKICBmaWx0ZXIoSWQgPT0gMzYpICU+JQogIHNsaWNlKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6d2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikpICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PS13aW5nX2xfYW5nX19yYWQsIGNvbG91ciA9ICIjRjg3NjZEIikpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9d2luZ19yX2FuZ19fcmFkLCBjb2xvdXIgPSAiIzAwQkZDNCIpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PWMoaWZlbHNlKG1heF93aW5nX2FuZ19fcmFkPj0oMjUqcGkvMTgwKSwxLjYsLTEpKSkpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9YyhpZmVsc2UoV2luZ0dlc3R1cmU9PTEsV2luZ0dlc3R1cmUrMC44LFdpbmdHZXN0dXJlLTEpKSkpICsKICAgICNnZW9tX3BvaW50KGFlcyh5PWMoaWZlbHNlKFdpbmdHZXN0dXJlPT0xLFdpbmdHZXN0dXJlKzAuNixXaW5nR2VzdHVyZS0xKSkpKSArCiAgeWxpbSgwLDIpCmBgYAoKCgo8YnIvPgo8YnIvPgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF82IikgJT4lIAogIGZpbHRlcihJZCA9PSA3KSAlPiUKICBzbGljZSh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqNjAwKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqNjAwKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKSAlPiUKICBnZ3Bsb3QoYWVzKHg9RnJhbWUpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PS13aW5nX2xfYW5nX19yYWQsIGNvbG91ciA9ICIjRjg3NjZEIikpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9d2luZ19yX2FuZ19fcmFkLCBjb2xvdXIgPSAiIzAwQkZDNCIpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PWMoaWZlbHNlKG1heF93aW5nX2FuZ19fcmFkPj0oMzUqcGkvMTgwKSwxLjYsLTEpKSkpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9YyhpZmVsc2UoV2luZ0dlc3R1cmU9PTEsV2luZ0dlc3R1cmUrMC44LFdpbmdHZXN0dXJlLTEpKSkpICsKICAgICNnZW9tX3BvaW50KGFlcyh5PWMoaWZlbHNlKFdpbmdHZXN0dXJlPT0xLFdpbmdHZXN0dXJlKzAuNixXaW5nR2VzdHVyZS0xKSkpKSArCiAgeWxpbSgwLDIpCmBgYAoKCgo8YnIvPgo8YnIvPgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKEZpbGVOYW1lID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyMzRfMiIpICU+JSAKICBmaWx0ZXIoSWQgPT0gNSkgJT4lCiAgc2xpY2Uod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPD0gKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSo2MDApKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkgJT4lCiAgZ2dwbG90KGFlcyh4PUZyYW1lKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT0td2luZ19sX2FuZ19fcmFkLCBjb2xvdXIgPSAiI0Y4NzY2RCIpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PXdpbmdfcl9hbmdfX3JhZCwgY29sb3VyID0gIiMwMEJGQzQiKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT1jKGlmZWxzZShtYXhfd2luZ19hbmdfX3JhZD49KDM1KnBpLzE4MCksMS42LC0xKSkpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PWMoaWZlbHNlKFdpbmdHZXN0dXJlPT0xLFdpbmdHZXN0dXJlKzAuOCxXaW5nR2VzdHVyZS0xKSkpKSArCiAgICAjZ2VvbV9wb2ludChhZXMoeT1jKGlmZWxzZShXaW5nR2VzdHVyZT09MSxXaW5nR2VzdHVyZSswLjYsV2luZ0dlc3R1cmUtMSkpKSkgKwogIHlsaW0oMCwyKQpgYGAKCgoKCgoKCgoKCjxici8+Cjxici8+CgoKPGJyLz4KPGJyLz4KCgoKCgoKCiMjIyAqKkZhY2luZyBhbmdsZSBhdCBzdGFydCBhbmQgZW5kIG9mIGVhY2ggYm91dCoqCgoKCgpgYGB7cn0KdGVtcCA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlIT0iQ1MgZmVtYWxlIikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpCiAgCnVuaXFfZmx5IDwtIHVuaXF1ZSh0ZW1wJHVuaXF1ZV9mbHkpCmZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcgPC0gdGliYmxlKCkKZm9yIChmbHkgaW4gdW5pcV9mbHkpIHsKICB0ZW1wMiA8LSBmaWx0ZXIodGVtcCwgdW5pcXVlX2ZseSA9PSBmbHkpCiAgYm91dHMgPC0gcmxlKHRlbXAyJFdpbmdHZXN0dXJlKQogIAogIHN0YXJ0cyA8LSBhcy5udW1lcmljKCkKICBmb3IgKGkgaW4gc2VxKDEsbGVuZ3RoKHdoaWNoKGJvdXRzJHZhbHVlcz09MSkpLDEpKSB7CiAgICBzdGFydHNbaV0gPSBzdW0oYm91dHMkbGVuZ3Roc1sxOihpKjIpLTFdKSsxCiAgfQogIGVuZHMgPC0gYXMubnVtZXJpYygpCiAgZm9yIChpIGluIHNlcSgxLGxlbmd0aCh3aGljaChib3V0cyR2YWx1ZXM9PTEpKSwxKSkgewogICAgZW5kc1tpXSA9IHN1bShib3V0cyRsZW5ndGhzWzE6KGkqMildKQogIH0KICBnZW5vdHlwZSA9IHJlcCh1bmlxdWUodGVtcDIkZ2Vub3R5cGUpLGxlbmd0aCh3aGljaChib3V0cyR2YWx1ZXM9PTEpKSkKICB1bmlfaWQgPSByZXAodW5pcXVlKHRlbXAyJHVuaXF1ZV9mbHkpLGxlbmd0aCh3aGljaChib3V0cyR2YWx1ZXM9PTEpKSkKICAKICB0ZW1wX3RpYmJsZSA8LSB0aWJibGUodW5pcXVlX2ZseSA9IHVuaV9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgZ2Vub3R5cGUgPSBnZW5vdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgZmFjaW5nX2F0X3N0YXJ0ID0gdGVtcDIkZmFjaW5nX2FuZ2xlX19yYWRbc3RhcnRzXSwKICAgICAgICAgICAgICAgICAgICAgICAgZmFjaW5nX2F0X2VuZCA9IHRlbXAyJGZhY2luZ19hbmdsZV9fcmFkW2VuZHNdCiAgICAgICAgICAgICAgICAgICAgICAgICkKICBmYWNpbmdfc3RhcnRfYW5kX2VuZF93aW5nIDwtIGJpbmRfcm93cyhmYWNpbmdfc3RhcnRfYW5kX2VuZF93aW5nLHRlbXBfdGliYmxlKQp9CmZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcKYGBgCgoKCjxici8+Cjxici8+CgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02fQpwMSA8LSBnZ3Bsb3QoZmFjaW5nX3N0YXJ0X2FuZF9lbmRfd2luZywgYWVzKHg9Z2Vub3R5cGUseT1mYWNpbmdfYXRfc3RhcnQpKSArCiAgZ2VvbV9ib3hwbG90KCkKcDIgPC0gZ2dwbG90KGZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcsIGFlcyh4PWdlbm90eXBlLHk9ZmFjaW5nX2F0X2VuZCkpICsKICBnZW9tX2JveHBsb3QoKQpwMyA8LSBnZ3Bsb3QoZmFjaW5nX3N0YXJ0X2FuZF9lbmRfd2luZywgYWVzKHg9Z2Vub3R5cGUseT1mYWNpbmdfYXRfc3RhcnQvZmFjaW5nX2F0X2VuZCkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgeWxpbSgwLDIpCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIscDMpLAogICAgICAgICAgbGFiZWxzID0gYygiRmFjaW5nIEFuZ2xlIGF0IFN0YXJ0IiwiRmFjaW5nIEFuZ2xlIGF0IEVuZCIsIlJhdGlvIHN0YXJ0OmVuZCIpLAogICAgICAgICAgaGp1c3QgPSAtMC4yLAogICAgICAgICAgdmp1c3QgPSAxLjYsCiAgICAgICAgICBuY29sID0gMywKICAgICAgICAgIG5yb3cgPSAxKQoKYGBgCgoKCjxici8+Cjxici8+CgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9Nn0KcDEgPC0gZ2dwbG90KGZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcsIGFlcyh4PWdlbm90eXBlLHk9ZmFjaW5nX2F0X3N0YXJ0LWZhY2luZ19hdF9lbmQpKSArCiAgZ2VvbV9ib3hwbG90KCkrCiAgeWxpbSgtMC41LDAuNSkKcDIgPC0gZ2dwbG90KGZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcsIGFlcyh4PWdlbm90eXBlLHk9ZmFjaW5nX2F0X2VuZC1mYWNpbmdfYXRfc3RhcnQpKSArCiAgZ2VvbV9ib3hwbG90KCkrCiAgeWxpbSgtMC41LDAuNSkKcDMgPC0gZ2dwbG90KGZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcsIGFlcyh4PWdlbm90eXBlLHk9ZmFjaW5nX2F0X3N0YXJ0L2ZhY2luZ19hdF9lbmQpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIHlsaW0oMCwyKQpnZ2FycmFuZ2UocGxvdGxpc3QgPSBsaXN0KHAxLHAyLHAzKSwKICAgICAgICAgIGxhYmVscyA9IGMoIlN0YXJ0LUVuZCIsIkVuZC1TdGFydCIsIlJhdGlvIHN0YXJ0OmVuZCIpLAogICAgICAgICAgaGp1c3QgPSAtMC4yLAogICAgICAgICAgdmp1c3QgPSAxLjYsCiAgICAgICAgICBuY29sID0gMywKICAgICAgICAgIG5yb3cgPSAxKQpgYGAKCgoKCgoKCgo8YnIvPgo8YnIvPgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTZ9CnAxIDwtIGdncGxvdChmYWNpbmdfc3RhcnRfYW5kX2VuZF93aW5nLCBhZXMoeD1nZW5vdHlwZSx5PWZhY2luZ19hdF9zdGFydCkpICsKICBnZW9tX3Zpb2xpbigpCnAyIDwtIGdncGxvdChmYWNpbmdfc3RhcnRfYW5kX2VuZF93aW5nLCBhZXMoeD1nZW5vdHlwZSx5PWZhY2luZ19hdF9lbmQpKSArCiAgZ2VvbV92aW9saW4oKQpnZ2FycmFuZ2UocGxvdGxpc3QgPSBsaXN0KHAxLHAyKSwKICAgICAgICAgIGxhYmVscyA9IGMoIkZhY2luZyBBbmdsZSBhdCBTdGFydCIsIkZhY2luZyBBbmdsZSBhdCBFbmQiKSwKICAgICAgICAgICNoanVzdCA9IC0wLjYsCiAgICAgICAgICAjdmp1c3QgPSAyLAogICAgICAgICAgbmNvbCA9IDIsCiAgICAgICAgICBucm93ID0gMSkKCmBgYAoKCgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCjxici8+Cjxici8+CgoKIyMjICoqTWVhbiBmYWNpbmcgYW5nbGUgYXQgc3RhcnQgYW5kIGVuZCBvZiBib3V0KioKCgpgYGB7cn0KdGVtcCA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlIT0iQ1MgZmVtYWxlIikgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpCiAgCnVuaXFfZmx5IDwtIHVuaXF1ZSh0ZW1wJHVuaXF1ZV9mbHkpCmZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcgPC0gdGliYmxlKCkKZm9yIChmbHkgaW4gdW5pcV9mbHkpIHsKICB0ZW1wMiA8LSBmaWx0ZXIodGVtcCwgdW5pcXVlX2ZseSA9PSBmbHkpCiAgYm91dHMgPC0gcmxlKHRlbXAyJFdpbmdHZXN0dXJlKQogIAogIHN0YXJ0cyA8LSBhcy5udW1lcmljKCkKICBmb3IgKGkgaW4gc2VxKDEsbGVuZ3RoKHdoaWNoKGJvdXRzJHZhbHVlcz09MSkpLDEpKSB7CiAgICBzdGFydHNbaV0gPSBzdW0oYm91dHMkbGVuZ3Roc1sxOihpKjIpLTFdKSsxCiAgfQogIGVuZHMgPC0gYXMubnVtZXJpYygpCiAgZm9yIChpIGluIHNlcSgxLGxlbmd0aCh3aGljaChib3V0cyR2YWx1ZXM9PTEpKSwxKSkgewogICAgZW5kc1tpXSA9IHN1bShib3V0cyRsZW5ndGhzWzE6KGkqMildKQogIH0KICBnZW5vdHlwZSA9IHVuaXF1ZSh0ZW1wMiRnZW5vdHlwZSkKICB1bmlfaWQgPSB1bmlxdWUodGVtcDIkdW5pcXVlX2ZseSkKICAKICB0ZW1wX3RpYmJsZSA8LSB0aWJibGUodW5pcXVlX2ZseSA9IHVuaV9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgZ2Vub3R5cGUgPSBnZW5vdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgZmFjaW5nX2F0X3N0YXJ0ID0gbWVhbih0ZW1wMiRmYWNpbmdfYW5nbGVfX3JhZFtzdGFydHNdKSwKICAgICAgICAgICAgICAgICAgICAgICAgZmFjaW5nX2F0X2VuZCA9IG1lYW4odGVtcDIkZmFjaW5nX2FuZ2xlX19yYWRbZW5kc10pCiAgICAgICAgICAgICAgICAgICAgICAgICkKICBmYWNpbmdfc3RhcnRfYW5kX2VuZF93aW5nIDwtIGJpbmRfcm93cyhmYWNpbmdfc3RhcnRfYW5kX2VuZF93aW5nLHRlbXBfdGliYmxlKQp9CmZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcKYGBgCgoKCgo8YnIvPgo8YnIvPgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9Nn0KcDEgPC0gZ2dwbG90KGZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcsIGFlcyh4PWdlbm90eXBlLHk9ZmFjaW5nX2F0X3N0YXJ0KSkgKwogIGdlb21fYm94cGxvdCgpICsKICB5bGltKDAsMSkKcDIgPC0gZ2dwbG90KGZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcsIGFlcyh4PWdlbm90eXBlLHk9ZmFjaW5nX2F0X2VuZCkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgeWxpbSgwLDEpCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIpLAogICAgICAgICAgbGFiZWxzID0gYygibWVhbiBGYWNpbmcgQW5nbGUgYXQgU3RhcnQiLCJtZWFuIEZhY2luZyBBbmdsZSBhdCBFbmQiKSwKICAgICAgICAgICNoanVzdCA9IC0wLjYsCiAgICAgICAgICAjdmp1c3QgPSAyLAogICAgICAgICAgbmNvbCA9IDIsCiAgICAgICAgICBucm93ID0gMSkKCmBgYAoKCgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCiMjIyAqKk1lZGlhbiBmYWNpbmcgYW5nbGUgYXQgc3RhcnQgYW5kIGVuZCBvZiBib3V0ICh1c2luZyBXaW5nR2VzdHVyZSkqKgoKCmBgYHtyfQp0ZW1wIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUhPSJDUyBmZW1hbGUiKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikKICAKdW5pcV9mbHkgPC0gdW5pcXVlKHRlbXAkdW5pcXVlX2ZseSkKZmFjaW5nX3N0YXJ0X2FuZF9lbmRfd2luZyA8LSB0aWJibGUoKQpmb3IgKGZseSBpbiB1bmlxX2ZseSkgewogIHRlbXAyIDwtIGZpbHRlcih0ZW1wLCB1bmlxdWVfZmx5ID09IGZseSkKICBib3V0cyA8LSBybGUodGVtcDIkV2luZ0dlc3R1cmUpCiAgCiAgc3RhcnRzIDwtIGFzLm51bWVyaWMoKQogIGZvciAoaSBpbiBzZXEoMSxsZW5ndGgod2hpY2goYm91dHMkdmFsdWVzPT0xKSksMSkpIHsKICAgIHN0YXJ0c1tpXSA9IHN1bShib3V0cyRsZW5ndGhzWzE6KGkqMiktMV0pKzEKICB9CiAgZW5kcyA8LSBhcy5udW1lcmljKCkKICBmb3IgKGkgaW4gc2VxKDEsbGVuZ3RoKHdoaWNoKGJvdXRzJHZhbHVlcz09MSkpLDEpKSB7CiAgICBlbmRzW2ldID0gc3VtKGJvdXRzJGxlbmd0aHNbMTooaSoyKV0pCiAgfQogIGdlbm90eXBlID0gdW5pcXVlKHRlbXAyJGdlbm90eXBlKQogIHVuaV9pZCA9IHVuaXF1ZSh0ZW1wMiR1bmlxdWVfZmx5KQogIAogIHRlbXBfdGliYmxlIDwtIHRpYmJsZSh1bmlxdWVfZmx5ID0gdW5pX2lkLAogICAgICAgICAgICAgICAgICAgICAgICBnZW5vdHlwZSA9IGdlbm90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICBmYWNpbmdfYXRfc3RhcnQgPSBtZWRpYW4odGVtcDIkZmFjaW5nX2FuZ2xlX19yYWRbc3RhcnRzXSksCiAgICAgICAgICAgICAgICAgICAgICAgIGZhY2luZ19hdF9lbmQgPSBtZWRpYW4odGVtcDIkZmFjaW5nX2FuZ2xlX19yYWRbZW5kc10pCiAgICAgICAgICAgICAgICAgICAgICAgICkKICBmYWNpbmdfc3RhcnRfYW5kX2VuZF93aW5nIDwtIGJpbmRfcm93cyhmYWNpbmdfc3RhcnRfYW5kX2VuZF93aW5nLHRlbXBfdGliYmxlKQp9CmZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcKYGBgCgoKCgo8YnIvPgo8YnIvPgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9OH0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSE9IkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieSh1bmlxdWVfZmx5KSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihXaW5nR2VzdHVyZT09MSkgJT4lIAogIHN1bW1hcmlzZShnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksCiAgICAgICAgICAgIG1lZGlhbl9mYWNpbmcgPSBtZWRpYW4oZmFjaW5nX2FuZ2xlX19yYWQpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9bWVkaWFuX2ZhY2luZykpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCwwLjUpCnAyIDwtIGdncGxvdChmYWNpbmdfc3RhcnRfYW5kX2VuZF93aW5nLCBhZXMoeD1nZW5vdHlwZSx5PWZhY2luZ19hdF9zdGFydCkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgeWxpbSgwLDAuNSkKcDMgPC0gZ2dwbG90KGZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcsIGFlcyh4PWdlbm90eXBlLHk9ZmFjaW5nX2F0X2VuZCkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgeWxpbSgwLDAuNSkKcDQgPC0gZ2dwbG90KGZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcsIGFlcyh4PWdlbm90eXBlLHk9ZmFjaW5nX2F0X3N0YXJ0L2ZhY2luZ19hdF9lbmQpKSArCiAgZ2VvbV9ib3hwbG90KCkgIysKICAjeWxpbSgwLDAuNSkKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMixwMyxwNCksCiAgICAgICAgICBsYWJlbHMgPSBjKCJtZWRpYW4gRmFjaW5nIGFuZ2xlIHRocm91Z2hvdXQiLCJtZWRpYW4gYXQgU3RhcnQgb2YgZWFjaCBib3V0IiwibWVkaWFuIGF0IEVuZCBvZiBlYWNoIGJvdXQiLCJyYXRpbyBzdGFydDplbmQiKSwKICAgICAgICAgIGhqdXN0ID0gLTAuMiwKICAgICAgICAgIHZqdXN0ID0gMiwKICAgICAgICAgIG5jb2wgPSA0LAogICAgICAgICAgbnJvdyA9IDEpCmBgYAoKCjxici8+Cjxici8+CgoKPGJyLz4KPGJyLz4KCgoKIyMjICoqTWVkaWFuIGZhY2luZyBhbmdsZSBhdCBzdGFydCBhbmQgZW5kIG9mIGJvdXQgKHVzaW5nID4zNWRlZykqKgoKCmBgYHtyfQp0ZW1wIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUhPSJDUyBmZW1hbGUiKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikKICAKdW5pcV9mbHkgPC0gdW5pcXVlKHRlbXAkdW5pcXVlX2ZseSkKZmFjaW5nX3N0YXJ0X2FuZF9lbmRfd2luZyA8LSB0aWJibGUoKQpmb3IgKGZseSBpbiB1bmlxX2ZseSkgewogIHRlbXAyIDwtIGZpbHRlcih0ZW1wLCB1bmlxdWVfZmx5ID09IGZseSkKICAjYm91dHMgPC0gcmxlKHRlbXAyJFdpbmdHZXN0dXJlKQogIHRlbXAyJGJpbl9tYXhfd2luZyA8LSBpZmVsc2UodGVtcDIkbWF4X3dpbmdfYW5nX19yYWQgPj0gKDM1KnBpLzE4MCksMSwwKQogIHRlbXAyJGJpbl9tYXhfd2luZyA8LSB0ZW1wMiRiaW5fbWF4X3dpbmcgJT4lIHJlcGxhY2VfbmEoMCkKICBib3V0cyA8LSBybGUodGVtcDIkYmluX21heF93aW5nKQoKICBzdGFydHMgPC0gYXMubnVtZXJpYygpCiAgZm9yIChpIGluIHNlcSgxLGxlbmd0aCh3aGljaChib3V0cyR2YWx1ZXM9PTEpKSwxKSkgewogICAgc3RhcnRzW2ldID0gc3VtKGJvdXRzJGxlbmd0aHNbMTooaSoyKS0xXSkrMQogIH0KICBlbmRzIDwtIGFzLm51bWVyaWMoKQogIGZvciAoaSBpbiBzZXEoMSxsZW5ndGgod2hpY2goYm91dHMkdmFsdWVzPT0xKSksMSkpIHsKICAgIGVuZHNbaV0gPSBzdW0oYm91dHMkbGVuZ3Roc1sxOihpKjIpXSkKICB9CiAgZ2Vub3R5cGUgPSB1bmlxdWUodGVtcDIkZ2Vub3R5cGUpCiAgdW5pX2lkID0gdW5pcXVlKHRlbXAyJHVuaXF1ZV9mbHkpCiAgCiAgdGVtcF90aWJibGUgPC0gdGliYmxlKHVuaXF1ZV9mbHkgPSB1bmlfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgIGdlbm90eXBlID0gZ2Vub3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgIGZhY2luZ19hdF9zdGFydCA9IG1lZGlhbih0ZW1wMiRmYWNpbmdfYW5nbGVfX3JhZFtzdGFydHNdKSwKICAgICAgICAgICAgICAgICAgICAgICAgZmFjaW5nX2F0X2VuZCA9IG1lZGlhbih0ZW1wMiRmYWNpbmdfYW5nbGVfX3JhZFtlbmRzXSkKICAgICAgICAgICAgICAgICAgICAgICAgKQogIGZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcgPC0gYmluZF9yb3dzKGZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcsdGVtcF90aWJibGUpCn0KZmFjaW5nX3N0YXJ0X2FuZF9lbmRfd2luZwpgYGAKCgoKPGJyLz4KPGJyLz4KCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD04fQpwMSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlIT0iQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKG1heF93aW5nX2FuZ19fcmFkID4gKDM1KnBpLzE4MCkpICU+JQogIHN1bW1hcmlzZShnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksCiAgICAgICAgICAgIG1lZGlhbl9mYWNpbmcgPSBtZWRpYW4oZmFjaW5nX2FuZ2xlX19yYWQpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9bWVkaWFuX2ZhY2luZykpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCwwLjUpCnAyIDwtIGdncGxvdChmYWNpbmdfc3RhcnRfYW5kX2VuZF93aW5nLCBhZXMoeD1nZW5vdHlwZSx5PWZhY2luZ19hdF9zdGFydCkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgeWxpbSgwLDAuNSkKcDMgPC0gZ2dwbG90KGZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcsIGFlcyh4PWdlbm90eXBlLHk9ZmFjaW5nX2F0X2VuZCkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgeWxpbSgwLDAuNSkKcDQgPC0gZ2dwbG90KGZhY2luZ19zdGFydF9hbmRfZW5kX3dpbmcsIGFlcyh4PWdlbm90eXBlLHk9ZmFjaW5nX2F0X3N0YXJ0L2ZhY2luZ19hdF9lbmQpKSArCiAgZ2VvbV9ib3hwbG90KCkgIysKICAjeWxpbSgwLDAuNSkKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMixwMyxwNCksCiAgICAgICAgICBsYWJlbHMgPSBjKCJtZWRpYW4gRmFjaW5nIGFuZ2xlIHRocm91Z2hvdXQiLCJtZWRpYW4gYXQgU3RhcnQgb2YgZWFjaCBib3V0IiwibWVkaWFuIGF0IEVuZCBvZiBlYWNoIGJvdXQiLCJyYXRpbyBzdGFydDplbmQiKSwKICAgICAgICAgIGhqdXN0ID0gLTAuMiwKICAgICAgICAgIHZqdXN0ID0gMiwKICAgICAgICAgIG5jb2wgPSA0LAogICAgICAgICAgbnJvdyA9IDEpCgpgYGAKCgoKCgoKCgo8YnIvPgo8YnIvPgoKCjxici8+Cjxici8+CgoKCgoKCiMjIyAqKkZhY2luZyBhbmdsZXMgd2l0aCB3aW5nIGV4dGVuZGVkIHVzaW5nIFdpbmdHZXN0dXJlKioKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD02fQpwMSA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlIT0iQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKFdpbmdHZXN0dXJlPT0xKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9ZmFjaW5nX2FuZ2xlX19yYWQpKSArCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICB5bGltKDAsMSkKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSE9IkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieSh1bmlxdWVfZmx5KSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihXaW5nR2VzdHVyZT09MSkgJT4lIAogIHN1bW1hcmlzZShnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksCiAgICAgICAgICAgIG1lZGlhbl9mYWNpbmcgPSBtZWRpYW4oZmFjaW5nX2FuZ2xlX19yYWQpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9bWVkaWFuX2ZhY2luZykpICsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHlsaW0oMCwxKQpwMyA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlIT0iQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKSAlPiUgCiAgZmlsdGVyKFdpbmdHZXN0dXJlPT0xKSAlPiUgCiAgc3VtbWFyaXNlKGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSwKICAgICAgICAgICAgbWVhbl9mYWNpbmcgPSBtZWFuKGZhY2luZ19hbmdsZV9fcmFkKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSx5PW1lYW5fZmFjaW5nKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgeWxpbSgwLDEpCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIscDMpLAogICAgICAgICAgbGFiZWxzID0gYygiRmFjaW5nIEFuZ2xlIiwibWVkaWFuIEZhY2luZyBBbmdsZSIsIm1lYW4gRmFjaW5nIEFuZ2xlIiksCiAgICAgICAgICAjaGp1c3QgPSAtMC42LAogICAgICAgICAgI3ZqdXN0ID0gMiwKICAgICAgICAgIG5jb2wgPSAzLAogICAgICAgICAgbnJvdyA9IDEpCmBgYAoKCgo8YnIvPgo8YnIvPgoKCjxici8+Cjxici8+CgoKCgojIyMgKipGYWNpbmcgYW5nbGVzIHdpdGggd2luZyBleHRlbmRlZCB1c2luZyBtYXhfd2luZz4zNSoqCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTZ9CnAxIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUhPSJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpICU+JSAKICBmaWx0ZXIobWF4X3dpbmdfYW5nX19yYWQgPiAoMzUqcGkvMTgwKSkgJT4lCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9ZmFjaW5nX2FuZ2xlX19yYWQpKSArCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICB5bGltKDAsMSkKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSE9IkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieSh1bmlxdWVfZmx5KSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICBzdW1tYXJpc2UoZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpLAogICAgICAgICAgICBtZWRpYW5fZmFjaW5nID0gbWVkaWFuKGZhY2luZ19hbmdsZV9fcmFkKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSx5PW1lZGlhbl9mYWNpbmcpKSArCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICB5bGltKDAsMSkKcDMgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSE9IkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieSh1bmlxdWVfZmx5KSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICBzdW1tYXJpc2UoZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpLAogICAgICAgICAgICBtZWFuX2ZhY2luZyA9IG1lYW4oZmFjaW5nX2FuZ2xlX19yYWQpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9bWVhbl9mYWNpbmcpKSArCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICB5bGltKDAsMSkKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMixwMyksCiAgICAgICAgICBsYWJlbHMgPSBjKCJGYWNpbmcgQW5nbGUiLCJtZWRpYW4gRmFjaW5nIEFuZ2xlIiwibWVhbiBGYWNpbmcgQW5nbGUiKSwKICAgICAgICAgICNoanVzdCA9IC0wLjYsCiAgICAgICAgICAjdmp1c3QgPSAyLAogICAgICAgICAgbmNvbCA9IDMsCiAgICAgICAgICBucm93ID0gMSkKYGBgCgogIAoKPGJyLz4KPGJyLz4KCgoKCgpgYGB7cn0KdGVzdF9zdGF0X3RpYmJsZTAgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSE9IkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieSh1bmlxdWVfZmx5KSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikgJT4lIAogIGZpbHRlcihtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApKSAlPiUKICBzdW1tYXJpc2UoZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpLAogICAgICAgICAgICBmYWNpbmcgPSBtZWRpYW4oZmFjaW5nX2FuZ2xlX19yYWQpKSAKYW92MCA8LSBhb3YoZmFjaW5nfmdlbm90eXBlLGRhdGEgPSB0ZXN0X3N0YXRfdGliYmxlMCkKI3N1bW1hcnkoYW92MCkKVHVrZXlIU0QoYW92MCkKYGBgCgoKCgoKCgoKCgoKCgoKCjxici8+Cjxici8+CgoKPGJyLz4KPGJyLz4KCgo8YnIvPgo8YnIvPgoKCjxici8+Cjxici8+CgoKPGJyLz4KPGJyLz4KCgoKCmBgYHtyfQp0ZXN0IDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihJZCA9PSAzNikgCmBgYAoKCmBgYHtyfQp0ZW1wMiA8LSB0ZXN0CgojYm91dHMgPC0gcmxlKHRlbXAyJFdpbmdHZXN0dXJlKQp0ZW1wMiRiaW5fbWF4X3dpbmcgPC0gaWZlbHNlKHRlbXAyJG1heF93aW5nX2FuZ19fcmFkID4gKDM1KnBpLzE4MCksMSwwKQp0ZW1wMiRiaW5fbWF4X3dpbmcgPC0gdGVtcDIkYmluX21heF93aW5nICU+JSByZXBsYWNlX25hKDApCmJvdXRzIDwtIHJsZSh0ZW1wMiRiaW5fbWF4X3dpbmcpCgpzdGFydHMgPC0gYXMubnVtZXJpYygpCmZvciAoaSBpbiBzZXEoMSxsZW5ndGgod2hpY2goYm91dHMkdmFsdWVzPT0xKSksMSkpIHsKICBzdGFydHNbaV0gPSBzdW0oYm91dHMkbGVuZ3Roc1sxOihpKjIpLTFdKSsxCn0KZW5kcyA8LSBhcy5udW1lcmljKCkKZm9yIChpIGluIHNlcSgxLGxlbmd0aCh3aGljaChib3V0cyR2YWx1ZXM9PTEpKSwxKSkgewogIGVuZHNbaV0gPSBzdW0oYm91dHMkbGVuZ3Roc1sxOihpKjIpXSkKfQpnZW5vdHlwZSA9IHJlcCh1bmlxdWUodGVtcDIkZ2Vub3R5cGUpLGxlbmd0aCh3aGljaChib3V0cyR2YWx1ZXM9PTEpKSkKdW5pX2lkID0gcmVwKHVuaXF1ZSh0ZW1wMiR1bmlxdWVfZmx5KSxsZW5ndGgod2hpY2goYm91dHMkdmFsdWVzPT0xKSkpCgp0ZW1wX3RpYmJsZSA8LSB0aWJibGUodW5pcXVlX2ZseSA9IHVuaV9pZCwKICAgICAgICAgICAgICAgICAgICAgIGdlbm90eXBlID0gZ2Vub3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICBmYWNpbmdfYXRfc3RhcnQgPSB0ZW1wMiRmYWNpbmdfYW5nbGVfX3JhZFtzdGFydHNdLAogICAgICAgICAgICAgICAgICAgICAgZmFjaW5nX2F0X2VuZCA9IHRlbXAyJGZhY2luZ19hbmdsZV9fcmFkW2VuZHNdCiAgICAgICAgICAgICAgICAgICAgICApCnRlbXBfdGliYmxlCgpgYGAKCgpgYGB7cn0Kc3RhcnRzID0gZm9yIChpIGluIHNlcSgxLGxlbmd0aCh3aGljaChib3V0cyR2YWx1ZXM9PTEpKSwxKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRzW2ldID0gc3VtKGJvdXRzJGxlbmd0aHNbMTooaSoyKS0xXSkrMQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0Kc3RhcnRzCmBgYAoKCgoKYGBge3J9Cgp0ZXN0JGJpbl9tYXhfd2luZyA8LSBpZmVsc2UodGVzdCRtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApLDEsMCkKdGVzdCRiaW5fbWF4X3dpbmcgPC0gdGVzdCRiaW5fbWF4X3dpbmcgJT4lIHJlcGxhY2VfbmEoMCkKI3Rlc3QkYmluX21heF93aW5nCmJvdXRzIDwtIHJsZSh0ZXN0JGJpbl9tYXhfd2luZykKYm91dHMKYGBgCgoKYGBge3J9CmJvdXRzIDwtIHJsZSh0ZXN0JFdpbmdHZXN0dXJlKQpib3V0cwpgYGAKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CnRlc3QgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKElkID09IDM2KSAKCnRlc3QkYmluX21heF93aW5nIDwtIGlmZWxzZSh0ZXN0JG1heF93aW5nX2FuZ19fcmFkID4gKDM1KnBpLzE4MCksMSwwKQp0ZXN0JGJpbl9tYXhfd2luZyA8LSB0ZXN0JGJpbl9tYXhfd2luZyAlPiUgcmVwbGFjZV9uYSgwKQoKdGVzdCAlPiUgCiAgc2xpY2Uod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTp3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSkgJT4lIAogIGdncGxvdChhZXMoeD1GcmFtZSkpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9LXdpbmdfbF9hbmdfX3JhZCwgY29sb3VyID0gIiNGODc2NkQiKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT13aW5nX3JfYW5nX19yYWQsIGNvbG91ciA9ICIjMDBCRkM0IikpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9YyhpZmVsc2UoYmluX21heF93aW5nPT0xLDEuNiwtMSkpKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT1jKGlmZWxzZShtYXhfd2luZ19hbmdfX3JhZD49KDM1KnBpLzE4MCksMS44LC0xKSkpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PWMoaWZlbHNlKFdpbmdHZXN0dXJlPT0xLFdpbmdHZXN0dXJlKzEsV2luZ0dlc3R1cmUtMSkpKSkgKwogICAgeWxpbSgwLDIuMikKYGBgCgpgYGB7cn0Kc3VtKHRlc3QkYmluX21heF93aW5nW3doaWNoLm1heCh0ZXN0JFNtb290aGVkQ291cnRzaGlwKTp3aGljaC5tYXgodGVzdCRTbW9vdGhlZENvcHVsYXRpb24pXT09dGVzdCRXaW5nR2VzdHVyZVt3aGljaC5tYXgodGVzdCRTbW9vdGhlZENvdXJ0c2hpcCk6d2hpY2gubWF4KHRlc3QkU21vb3RoZWRDb3B1bGF0aW9uKV0pCnN1bSh0ZXN0JGJpbl9tYXhfd2luZ1t3aGljaC5tYXgodGVzdCRTbW9vdGhlZENvdXJ0c2hpcCk6d2hpY2gubWF4KHRlc3QkU21vb3RoZWRDb3B1bGF0aW9uKV0hPXRlc3QkV2luZ0dlc3R1cmVbd2hpY2gubWF4KHRlc3QkU21vb3RoZWRDb3VydHNoaXApOndoaWNoLm1heCh0ZXN0JFNtb290aGVkQ29wdWxhdGlvbildKQpgYGAKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CnRlc3QgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjNfMyIpICU+JSAKICBmaWx0ZXIoSWQgPT0gMSkgCgp0ZXN0JGJpbl9tYXhfd2luZyA8LSBpZmVsc2UodGVzdCRtYXhfd2luZ19hbmdfX3JhZCA+ICgzNSpwaS8xODApLDEsMCkKdGVzdCRiaW5fbWF4X3dpbmcgPC0gdGVzdCRiaW5fbWF4X3dpbmcgJT4lIHJlcGxhY2VfbmEoMCkKCnRlc3QgJT4lIAogICNzbGljZSh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOndoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pKSAlPiUgCiAgZ2dwbG90KGFlcyh4PUZyYW1lKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT0td2luZ19sX2FuZ19fcmFkLCBjb2xvdXIgPSAiI0Y4NzY2RCIpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PXdpbmdfcl9hbmdfX3JhZCwgY29sb3VyID0gIiMwMEJGQzQiKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT1jKGlmZWxzZShiaW5fbWF4X3dpbmc9PTEsMS42LC0xKSkpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PWMoaWZlbHNlKG1heF93aW5nX2FuZ19fcmFkPj0oMzUqcGkvMTgwKSwxLjgsLTEpKSkpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9YyhpZmVsc2UoV2luZ0dlc3R1cmU9PTEsV2luZ0dlc3R1cmUrMSxXaW5nR2VzdHVyZS0xKSkpKSArCiAgICB5bGltKDAsMi4yKQpgYGAKCmBgYHtyfQpnZ19jb2xvcl9odWUoNCkKYGBgCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTZ9CnRlc3QgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjNfMyIpICU+JSAKICBmaWx0ZXIoSWQgPT0gMSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpCgp0ZXN0JGJpbl9tYXhfd2luZyA8LSBpZmVsc2UodGVzdCRtYXhfd2luZ19hbmdfX3JhZCA+PSAoMzUqcGkvMTgwKSwxLDApCnRlc3QkYmluX21heF93aW5nIDwtIHRlc3QkYmluX21heF93aW5nICU+JSByZXBsYWNlX25hKDApCgp0ZXN0ICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PWRpc3RfdG9fb3RoZXJfX21tLCBjb2xvdXIgPSAiI0Y4NzY2RCIpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PVNtb290aGVkRGlzdFRvT3RoZXItMSwgY29sb3VyID0gIiM3Q0FFMDAiKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT0oU21vb3RoZWRDb3B1bGF0aW9uLTIpLCBjb2xvdXI9ICIjMDBCRkM0IikpICsKCiAgICBnZW9tX3BvaW50KGFlcyh5PWMoaWZlbHNlKGJpbl9tYXhfd2luZz09MSwtMywtMTApKSkpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9YyhpZmVsc2UobWF4X3dpbmdfYW5nX19yYWQ+PSgzNSpwaS8xODApLC00LC0xMCkpKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT1jKGlmZWxzZShXaW5nR2VzdHVyZT09MSwtNiwtMTApKSkpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9YyhpZmVsc2UoU21vb3RoZWRDb3VydHNoaXA9PTEsMjAsLTEwKSkpKSArCiAgICB5bGltKC02LDIwKQpgYGAKCmBgYHtyfQptYXgodGVzdCRGcmFtZSkKYGBgCgoKCmBgYHtyfQp0ZW1wMiA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKEZpbGVOYW1lID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyM18zIikgJT4lIAogIGZpbHRlcihJZCA9PSAxKSAlPiUgCiAgZmlsdGVyKGRpc3RfdG9fb3RoZXJfX21tID4gMikKCiNib3V0cyA8LSBybGUodGVtcDIkV2luZ0dlc3R1cmUpCnRlbXAyJGJpbl9tYXhfd2luZyA8LSBpZmVsc2UodGVtcDIkbWF4X3dpbmdfYW5nX19yYWQgPj0gKDM1KnBpLzE4MCksMSwwKQp0ZW1wMiRiaW5fbWF4X3dpbmcgPC0gdGVtcDIkYmluX21heF93aW5nICU+JSByZXBsYWNlX25hKDApCmJvdXRzIDwtIHJsZSh0ZXN0JGJpbl9tYXhfd2luZykKCnN0YXJ0cyA8LSBhcy5udW1lcmljKCkKZm9yIChpIGluIHNlcSgxLGxlbmd0aCh3aGljaChib3V0cyR2YWx1ZXM9PTEpKSwxKSkgewogIHN0YXJ0c1tpXSA9IHN1bShib3V0cyRsZW5ndGhzWzE6KGkqMiktMV0pKzEKfQplbmRzIDwtIGFzLm51bWVyaWMoKQpmb3IgKGkgaW4gc2VxKDEsbGVuZ3RoKHdoaWNoKGJvdXRzJHZhbHVlcz09MSkpLDEpKSB7CiAgZW5kc1tpXSA9IHN1bShib3V0cyRsZW5ndGhzWzE6KGkqMildKQp9Cmdlbm90eXBlID0gdW5pcXVlKHRlbXAyJGdlbm90eXBlKQp1bmlfaWQgPSB1bmlxdWUodGVtcDIkdW5pcXVlX2ZseSkKCnRlbXBfdGliYmxlIDwtIHRpYmJsZSh1bmlxdWVfZmx5ID0gdW5pX2lkLAogICAgICAgICAgICAgICAgICAgICAgZ2Vub3R5cGUgPSBnZW5vdHlwZSwKICAgICAgICAgICAgICAgICAgICAgIGZhY2luZ19hdF9zdGFydCA9IG1lZGlhbih0ZW1wMiRmYWNpbmdfYW5nbGVfX3JhZFtzdGFydHNdKSwKICAgICAgICAgICAgICAgICAgICAgIGZhY2luZ19hdF9lbmQgPSBtZWRpYW4odGVtcDIkZmFjaW5nX2FuZ2xlX19yYWRbZW5kc10pCiAgICAgICAgICAgICAgICAgICAgICApCnRlbXBfdGliYmxlCmBgYAoKCgoKCmBgYHtyfQpib3V0cyA8LSBybGUodGVzdCRiaW5fbWF4X3dpbmcpCmJvdXRzCmBgYAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzXzMiKSAlPiUgCiAgZmlsdGVyKElkID09IDIxKSAlPiUgCiAgZ2dwbG90KGFlcyh4PUZyYW1lKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT1TbW9vdGhlZENvdXJ0c2hpcCwgY29sb3VyID0gIiNGODc2NkQiKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT0oU21vb3RoZWRDb3B1bGF0aW9uKzAuMSksIGNvbG91cj0gIiMwMEJGQzQiKSkgIysKICAgICN4bGltKDIwMDAsMzAwMCkKYGBgCgoKCgoKCgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihJZCA9PSAzNikgJT4lCiAgI3NsaWNlKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6d2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikpICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PXdpbmdfbF9hbmdfX3JhZCwgY29sb3VyID0gIiNGODc2NkQiKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT13aW5nX3JfYW5nX19yYWQsIGNvbG91ciA9ICIjMDBCRkM0IikpCiAgCmBgYAoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKElkID09IDM2KSAlPiUKICBzbGljZSh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOndoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pKSAlPiUgCiAgZ2dwbG90KGFlcyh4PUZyYW1lKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT0td2luZ19sX2FuZ19fcmFkLCBjb2xvdXIgPSAiI0Y4NzY2RCIpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PXdpbmdfcl9hbmdfX3JhZCwgY29sb3VyID0gIiMwMEJGQzQiKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT1jKGlmZWxzZShXaW5nR2VzdHVyZT09MSxXaW5nR2VzdHVyZSswLjYsV2luZ0dlc3R1cmUtMC4yKSkpKQpgYGAKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKEZpbGVOYW1lID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyMzRfMiIpICU+JSAKICBmaWx0ZXIoSWQgPT0gMzYpICU+JQogIHNsaWNlKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6d2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikpICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PS13aW5nX2xfYW5nX19yYWQsIGNvbG91ciA9ICIjRjg3NjZEIikpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9d2luZ19yX2FuZ19fcmFkLCBjb2xvdXIgPSAiIzAwQkZDNCIpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PWMoaWZlbHNlKFdpbmdHZXN0dXJlPT0xLFdpbmdHZXN0dXJlKzAuNixOQSkpKSkKYGBgCgoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD00fQphbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKEZpbGVOYW1lID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyMzRfMiIpICU+JSAKICBmaWx0ZXIoSWQgPT0gMzYpICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUseT1kaXN0X3RvX290aGVyX19tbSkpICsKICAgIGdlb21fcG9pbnQoYWVzKGNvbG91cj1jKGlmZWxzZShTbW9vdGhlZERpc3RUb090aGVyPjAuNSwibm90IGNvcHVsYXRpbmciLCJjb3B1bGF0aW5nIikpKSkrCiAgICBnZW9tX3BvaW50KGFlcyh5PWMoaWZlbHNlKFNtb290aGVkQ29wdWxhdGlvbj09MSxTbW9vdGhlZENvcHVsYXRpb24rNixOQSkpKSkKYGBgCgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTR9CmFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoRmlsZU5hbWUgPT0gIk1lZ2FuLTIwMTlfMDNfMDZfQ291cnRzaGlwLURzeFZnbHV0VE5UX01hbGVfMTIzNF8yIikgJT4lIAogIGZpbHRlcihJZCA9PSAzNikgJT4lIAogIGdncGxvdChhZXMoeD1GcmFtZSkpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9U21vb3RoZWREaXN0VG9PdGhlciwgY29sb3VyID0gIiNGODc2NkQiKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT0oU21vb3RoZWRDb3B1bGF0aW9uKzAuMSksIGNvbG91cj0gIiMwMEJGQzQiKSkgKwogICAgeGxpbSgyMDAwLDMwMDApCmBgYAoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9NH0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKElkID09IDM2KSAlPiUgCiAgZ2dwbG90KGFlcyh4PUZyYW1lKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT1TbW9vdGhlZENvdXJ0c2hpcCwgY29sb3VyID0gIiNGODc2NkQiKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT0oU21vb3RoZWRDb3B1bGF0aW9uKzAuMSksIGNvbG91cj0gIiMwMEJGQzQiKSkgIysKICAgICN4bGltKDIwMDAsMzAwMCkKYGBgCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCiMgKipUcnlpbmcgdG8gbWFrZSBmdW5jdGlvbnMgZm9yIGNvdXJ0c2hpcCB3aW5kb3cgYW5kIGNhbGN1bGF0ZSBpbmRpY2VzLi4uIHRoZXkgYXJlbid0IHdvcmtpbmcgcmlnaHQsIGFuZCBzZWVtIHRvIGJlIGlnbm9yaW5nIHRoZSBncm91cGluZyBvZiB0aGUgdGliYmxlIGFuZCByZXR1cm5pbmcgdGhlIHNhbWUgdmFsdWUgZm9yIGV2ZXJ5IGluZGl2aWR1YWwuLi4qKgoKSWYgaSBoYXZlIHRvIGZvciBsb29wIG92ZXIgdGhlIGdyb3VwcyBvZiBhIHRpYmJsZSwgdGhlIGJlbG93IGxpbmUgbWlnaHQgYmUgdXNlZnVsbC4KZGltKHVuaXF1ZShhbGxfcmF3ZGF0YVthbGxfcmF3ZGF0YSAlPiUgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSBncm91cF92YXJzKCldKSlbMV0KCgoKCgoKYGBge3J9CmNvdXJ0c2hpcF93aW5kb3cgPC0gZnVuY3Rpb24oaW5wdXQsd2luZD02MDAsLi4uKXsKICB0ZW1wX3RpYmJsZSA8LSBzdW1tYXJpc2UoaW5wdXQsIHN0YXJ0X29mX2NvdXJ0c2hpcCA9IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRfb2ZfY291cnRzaGlwID0gaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICApCiAgcmV0dXJuKHRlbXBfdGliYmxlJHN0YXJ0X29mX2NvdXJ0c2hpcDp0ZW1wX3RpYmJsZSRlbmRfb2ZfY291cnRzaGlwKQogICNyZXR1cm4oYyh0ZW1wX3RpYmJsZSRzdGFydF9vZl9jb3VydHNoaXAsdGVtcF90aWJibGUkZW5kX29mX2NvdXJ0c2hpcCkpCiAgI3JldHVybih0ZW1wX3RpYmJsZSkKfQpgYGAKCgpgYGB7cn0KY291cnRzaGlwX3dpbmRvdyA8LSBmdW5jdGlvbihpbnB1dCx3aW5kPTYwMCwuLi4pewogIHRlbXBfdGliYmxlIDwtIHN1bW1hcmlzZShpbnB1dCwgc3RhcnRfb2ZfY291cnRzaGlwID0gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZF9vZl9jb3VydHNoaXAgPSBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAjcmV0dXJuKHRlbXBfdGliYmxlJHN0YXJ0X29mX2NvdXJ0c2hpcDp0ZW1wX3RpYmJsZSRlbmRfb2ZfY291cnRzaGlwKQogIHJldHVybihjKHRlbXBfdGliYmxlJHN0YXJ0X29mX2NvdXJ0c2hpcCx0ZW1wX3RpYmJsZSRlbmRfb2ZfY291cnRzaGlwKSkKICAjcmV0dXJuKHRlbXBfdGliYmxlKQp9CmBgYAoKCgoKCgoKCmBgYHtyfQpjb3VydHNoaXBfd2luZG93KHRlc3QsIHdpbmQgPSA2MDApCmBgYAoKCgoKCmBgYHtyfQp0ZW1wIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUhPSJDUyBmZW1hbGUiKQoKdW5pcV9mbHkgPC0gdW5pcXVlKHRlbXAkdW5pcXVlX2ZseSkKY291cnRpbmdfZnJhbWVzIDwtIHRpYmJsZSgpCmZvciAoZmx5IGluIHVuaXFfZmx5KSB7CiAgdGVtcDIgPC0gdGVtcCAlPiUgZmlsdGVyKHVuaXF1ZV9mbHkgPT0gZmx5KSAKICB0ZW1wMiA8LSBzbGljZSh0ZW1wMiwgd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKQogIGNvdXJ0aW5nX2ZyYW1lcyA8LSBiaW5kX3Jvd3MoY291cnRpbmdfZnJhbWVzLHRlbXAyKQp9CmNvdXJ0aW5nX2ZyYW1lcwpgYGAKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTZ9CnRlc3QgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjNfMyIpICU+JSAKICBmaWx0ZXIoSWQgPT0gMSkgJT4lIAogIGZpbHRlcihkaXN0X3RvX290aGVyX19tbSA+IDIpCgojdGVzdCRiaW5fbWF4X3dpbmcgPC0gaWZlbHNlKHRlc3QkbWF4X3dpbmdfYW5nX19yYWQgPj0gKDM1KnBpLzE4MCksMSwwKQojdGVzdCRiaW5fbWF4X3dpbmcgPC0gdGVzdCRiaW5fbWF4X3dpbmcgJT4lIHJlcGxhY2VfbmEoMCkKCnRlc3QgJT4lIAogIGdncGxvdChhZXMoeD1GcmFtZSkpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9ZGlzdF90b19vdGhlcl9fbW0sIGNvbG91ciA9ICIjRjg3NjZEIikpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9U21vb3RoZWREaXN0VG9PdGhlci0xLCBjb2xvdXIgPSAiIzdDQUUwMCIpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PShTbW9vdGhlZENvcHVsYXRpb24tMiksIGNvbG91cj0gIiMwMEJGQzQiKSkgKwoKICAgICNnZW9tX3BvaW50KGFlcyh5PWMoaWZlbHNlKGJpbl9tYXhfd2luZz09MSwtMywtMTApKSkpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9YyhpZmVsc2UobWF4X3dpbmdfYW5nX19yYWQ+PSgzNSpwaS8xODApLC00LC0xMCkpKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT1jKGlmZWxzZShXaW5nR2VzdHVyZT09MSwtNiwtMTApKSkpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9YyhpZmVsc2UoU21vb3RoZWRDb3VydHNoaXA9PTEsMjAsLTEwKSkpKSArCiAgICB5bGltKC02LDIwKQpgYGAKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD02fQp0ZXN0IDwtIGNvdXJ0aW5nX2ZyYW1lcyAlPiUgCiAgZmlsdGVyKEZpbGVOYW1lID09ICJNZWdhbi0yMDE5XzAzXzA2X0NvdXJ0c2hpcC1Ec3hWZ2x1dFROVF9NYWxlXzEyM18zIikgJT4lIAogIGZpbHRlcihJZCA9PSAxKSAjJT4lIAogICNmaWx0ZXIoZGlzdF90b19vdGhlcl9fbW0gPiAyKQoKI3Rlc3QkYmluX21heF93aW5nIDwtIGlmZWxzZSh0ZXN0JG1heF93aW5nX2FuZ19fcmFkID49ICgzNSpwaS8xODApLDEsMCkKI3Rlc3QkYmluX21heF93aW5nIDwtIHRlc3QkYmluX21heF93aW5nICU+JSByZXBsYWNlX25hKDApCgp0ZXN0ICU+JSAKICBnZ3Bsb3QoYWVzKHg9RnJhbWUpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PWRpc3RfdG9fb3RoZXJfX21tLCBjb2xvdXIgPSAiI0Y4NzY2RCIpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PWlmZWxzZShTbW9vdGhlZERpc3RUb090aGVyPT0xLDEsLTEwKSwgY29sb3VyID0gIiM3Q0FFMDAiKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT1pZmVsc2UoU21vb3RoZWRDb3B1bGF0aW9uPT0wLC0yLC0xMCksIGNvbG91cj0gIiMwMEJGQzQiKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT1pZmVsc2UoQ29wdWxhdGlvbj09MCwtMSwtMTApLCBjb2xvdXI9ICIjMDBCRkM0IikpICsKCiAgICAjZ2VvbV9wb2ludChhZXMoeT1jKGlmZWxzZShiaW5fbWF4X3dpbmc9PTEsLTMsLTEwKSkpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PWMoaWZlbHNlKG1heF93aW5nX2FuZ19fcmFkPj0oMzUqcGkvMTgwKSwtNCwtMTApKSkpICsKICAgIGdlb21fcG9pbnQoYWVzKHk9YyhpZmVsc2UoV2luZ0dlc3R1cmU9PTEsLTYsLTEwKSkpKSArCiAgICBnZW9tX3BvaW50KGFlcyh5PWMoaWZlbHNlKFNtb290aGVkQ291cnRzaGlwPT0xLDIwLC0xMCkpKSkgKwogICAgZ2VvbV9wb2ludChhZXMoeT1jKGlmZWxzZShDb3VydHNoaXA9PTEsMTgsLTEwKSkpKSArCiAgICB5bGltKC02LDIwKQpgYGAKCgoKCgoKCgpgYGB7cn0KCmBgYAoKCmBgYHtyfQoKYGBgCgoKYGBge3J9CgpgYGAKCmBgYHtyfQoKYGBgCgoKYGBge3J9CgpgYGAKCgoKCgoKCgpgYGB7cn0KY2FsY3VsYXRlX2luZGljZXMgPC0gZnVuY3Rpb24oaW5wdXQgPSAuLGZlYXR1cmUsamFhYmE9VFJVRSx0aHJlc2g9TlVMTCx3aW5kPTYwMCl7CiAgaWYgKGZlYXR1cmUgJWluJSBuYW1lcyhpbnB1dCkpIHsKICAgIHZhcl9pbmQgPSBwYXN0ZTAoZmVhdHVyZSwiX2luZGV4IikKICAgIGlmIChqYWFiYSkgewogICAgICB0ZW1wX3RpYmJsZSA8LSBzdW1tYXJpc2UoaW5wdXQsIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgISF2YXJfaW5kIDo9IDEwMCpzdW0oaW5wdXRbW2ZlYXR1cmVdXVt3aGljaC5tYXgoaW5wdXRbWyJTbW9vdGhlZENvdXJ0c2hpcCJdXSk6aWZlbHNlKHdoaWNoLm1heChpbnB1dFtbIlNtb290aGVkQ29wdWxhdGlvbiJdXSkgPiB3aGljaC5tYXgoaW5wdXRbWyJTbW9vdGhlZENvdXJ0c2hpcCJdXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KGlucHV0W1siU21vb3RoZWRDb3B1bGF0aW9uIl1dKSA8PSAod2hpY2gubWF4KGlucHV0W1siU21vb3RoZWRDb3VydHNoaXAiXV0pKygyNSp3aW5kKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChpbnB1dFtbIlNtb290aGVkQ29wdWxhdGlvbiJdXSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KGlucHV0W1siU21vb3RoZWRDb3VydHNoaXAiXV0pKygyNSp3aW5kKSksbWF4KGlucHV0W1siRnJhbWUiXV0pKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoaW5wdXRbWyJTbW9vdGhlZENvdXJ0c2hpcCJdXSkrKDI1KndpbmQpKSxtYXgoaW5wdXRbWyJGcmFtZSJdXSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKV0pLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoKGlucHV0W1siRnJhbWUiXV1bd2hpY2gubWF4KGlucHV0W1siU21vb3RoZWRDb3VydHNoaXAiXV0pOmlmZWxzZSh3aGljaC5tYXgoaW5wdXRbWyJTbW9vdGhlZENvcHVsYXRpb24iXV0pID4gd2hpY2gubWF4KGlucHV0W1siU21vb3RoZWRDb3VydHNoaXAiXV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChpbnB1dFtbIlNtb290aGVkQ29wdWxhdGlvbiJdXSkgPD0gKHdoaWNoLm1heChpbnB1dFtbIlNtb290aGVkQ291cnRzaGlwIl1dKSsoMjUqd2luZCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoaW5wdXRbWyJTbW9vdGhlZENvcHVsYXRpb24iXV0pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChpbnB1dFtbIlNtb290aGVkQ291cnRzaGlwIl1dKSsoMjUqd2luZCkpLG1heChpbnB1dFtbIkZyYW1lIl1dKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KGlucHV0W1siU21vb3RoZWRDb3VydHNoaXAiXV0pKygyNSp3aW5kKSksbWF4KGlucHV0W1siRnJhbWUiXV0pKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICldKQogICAgICAgICAgICAgICAgKQogICAgfSBlbHNlIHsKICAgICAgdGVtcF90aWJibGUgPC0gc3VtbWFyaXNlKGlucHV0LCBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICEhdmFyX2luZCA6PSAxMDAqc3VtKGlucHV0W1tmZWF0dXJlXV1bd2hpY2gubWF4KGlucHV0W1siU21vb3RoZWRDb3VydHNoaXAiXV0pOmlmZWxzZSh3aGljaC5tYXgoaW5wdXRbWyJTbW9vdGhlZENvcHVsYXRpb24iXV0pID4gd2hpY2gubWF4KGlucHV0W1siU21vb3RoZWRDb3VydHNoaXAiXV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChpbnB1dFtbIlNtb290aGVkQ29wdWxhdGlvbiJdXSkgPD0gKHdoaWNoLm1heChpbnB1dFtbIlNtb290aGVkQ291cnRzaGlwIl1dKSsoMjUqd2luZCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoaW5wdXRbWyJTbW9vdGhlZENvcHVsYXRpb24iXV0pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChpbnB1dFtbIlNtb290aGVkQ291cnRzaGlwIl1dKSsoMjUqd2luZCkpLG1heChpbnB1dFtbIkZyYW1lIl1dKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KGlucHV0W1siU21vb3RoZWRDb3VydHNoaXAiXV0pKygyNSp3aW5kKSksbWF4KGlucHV0W1siRnJhbWUiXV0pKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICldPnRocmVzaCxuYS5ybSA9IFRSVUUpLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoKGlucHV0W1siRnJhbWUiXV1bd2hpY2gubWF4KGlucHV0W1siU21vb3RoZWRDb3VydHNoaXAiXV0pOmlmZWxzZSh3aGljaC5tYXgoaW5wdXRbWyJTbW9vdGhlZENvcHVsYXRpb24iXV0pID4gd2hpY2gubWF4KGlucHV0W1siU21vb3RoZWRDb3VydHNoaXAiXV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChpbnB1dFtbIlNtb290aGVkQ29wdWxhdGlvbiJdXSkgPD0gKHdoaWNoLm1heChpbnB1dFtbIlNtb290aGVkQ291cnRzaGlwIl1dKSsoMjUqd2luZCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoaW5wdXRbWyJTbW9vdGhlZENvcHVsYXRpb24iXV0pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChpbnB1dFtbIlNtb290aGVkQ291cnRzaGlwIl1dKSsoMjUqd2luZCkpLG1heChpbnB1dFtbIkZyYW1lIl1dKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KGlucHV0W1siU21vb3RoZWRDb3VydHNoaXAiXV0pKygyNSp3aW5kKSksbWF4KGlucHV0W1siRnJhbWUiXV0pKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICldKQogICAgICAgICAgICAgICAgKQogICAgfQogICAgcmV0dXJuKHRlbXBfdGliYmxlKQogIH0gZWxzZSB7CiAgICBtZXNzYWdlKHBhc3RlMChmZWF0dXJlLCAiIGRvZXMgbm90IGV4aXN0IGluIHRhYmxlIikpCiAgfQp9IApgYGAKCgoKCgoKYGBge3J9CmNhbGN1bGF0ZV9pbmRpY2VzIDwtIGZ1bmN0aW9uKGlucHV0LGZlYXR1cmUsamFhYmE9VFJVRSx0aHJlc2g9TlVMTCl7CiAgaWYgKGZlYXR1cmUgJWluJSBuYW1lcyhpbnB1dCkpIHsKICAgIHZhcl9pbmQgPSBwYXN0ZTAoZmVhdHVyZSwiX2luZGV4IikKICAgIGlmIChqYWFiYSkgewogICAgICB0ZW1wX3RpYmJsZSA8LSBzdW1tYXJpc2UoaW5wdXQsIGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgISF2YXJfaW5kIDo9IDEwMCpzdW0oaW5wdXRbW2ZlYXR1cmVdXVtjb3VydHNoaXBfd2luZG93KGlucHV0KV0pLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoKGlucHV0W1siRnJhbWUiXV1bY291cnRzaGlwX3dpbmRvdyhpbnB1dCldKQogICAgICAgICAgICAgICAgKQogICAgfSBlbHNlIHsKICAgICAgdGVtcF90aWJibGUgPC0gc3VtbWFyaXNlKGlucHV0LCBnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICEhdmFyX2luZCA6PSAxMDAqc3VtKGlucHV0W1tmZWF0dXJlXV1bY291cnRzaGlwX3dpbmRvdyhpbnB1dCldPnRocmVzaCxuYS5ybSA9IFRSVUUpLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoKGlucHV0W1siRnJhbWUiXV1bY291cnRzaGlwX3dpbmRvdyhpbnB1dCldKQogICAgICAgICAgICAgICAgKQogICAgfQogICAgcmV0dXJuKHRlbXBfdGliYmxlKQogIH0gZWxzZSB7CiAgICBtZXNzYWdlKHBhc3RlMChmZWF0dXJlLCAiIGRvZXMgbm90IGV4aXN0IGluIHRhYmxlIikpCiAgfQp9IApgYGAKCgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9NH0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBjYWxjdWxhdGVfaW5kaWNlcyhmZWF0dXJlID0gIm1heF93aW5nX2FuZ19fcmFkIixqYWFiYSA9IEZBTFNFLHRocmVzaCA9ICgyNSpwaS8xODApKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9bWF4X3dpbmdfYW5nX19yYWRfaW5kZXgpKSArCiAgICBnZW9tX2JveHBsb3QoKQpwMiA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIGNhbGN1bGF0ZV9pbmRpY2VzKGZlYXR1cmUgPSAid2luZ19sX2FuZ19fcmFkIixqYWFiYSA9IEZBTFNFLHRocmVzaCA9ICgyNSpwaS8xODApKSAlPiUgCiAgZ2dwbG90KGFlcyh4PWdlbm90eXBlLHk9d2luZ19sX2FuZ19fcmFkX2luZGV4KSkgKwogICAgZ2VvbV9ib3hwbG90KCkKcDMgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBjYWxjdWxhdGVfaW5kaWNlcyhmZWF0dXJlID0gIndpbmdfcl9hbmdfX3JhZCIsamFhYmEgPSBGQUxTRSx0aHJlc2ggPSAoMjUqcGkvMTgwKSkgJT4lIAogIGdncGxvdChhZXMoeD1nZW5vdHlwZSx5PXdpbmdfcl9hbmdfX3JhZF9pbmRleCkpICsKICAgIGdlb21fYm94cGxvdCgpCmdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIscDMpLAogICAgICAgICAgbGFiZWxzID0gYygid2luZyBpbmRleCIsImxlZnQgd2luZyIsInJpZ2h0IHdpbmciKSwKICAgICAgICAgIGhqdXN0ID0gLTAuNiwKICAgICAgICAgIHZqdXN0ID0gMiwKICAgICAgICAgIG5jb2wgPSAzLAogICAgICAgICAgbnJvdyA9IDEpCgpgYGAKCgoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9NH0KcDEgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIHN1bW1hcmlzZShnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksCiAgICAgICAgICAgIHdpbmdfaW5kZXggPSAxMDAqc3VtKG1heF93aW5nX2FuZ19fcmFkW2NvdXJ0c2hpcF93aW5kb3coaW5wdXQpXT4oNDAqcGkvMTgwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBUUlVFKS8KICAgICAgICAgICAgICBsZW5ndGgoRnJhbWVbY291cnRzaGlwX3dpbmRvdyhpbnB1dCldCiAgICAgICAgICAgICAgICAgICAgICkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUseT13aW5nX2luZGV4KSkgKwogICAgZ2VvbV9ib3hwbG90KCkKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIHN1bW1hcmlzZShnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksCiAgICAgICAgICAgIGxlZnRfd2luZ19pbmRleCA9IDEwMCpzdW0od2luZ19sX2FuZ19fcmFkW2NvdXJ0c2hpcF93aW5kb3coaW5wdXQpXTwoLTQwKnBpLzE4MCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hLnJtID0gVFJVRSkvCiAgICAgICAgICAgICAgbGVuZ3RoKEZyYW1lW2NvdXJ0c2hpcF93aW5kb3coaW5wdXQpXQogICAgICAgICAgICAgICAgICAgICApKSAlPiUKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUseT1sZWZ0X3dpbmdfaW5kZXgpKSArCiAgICBnZW9tX2JveHBsb3QoKQpwMyA8LSBhbGxfcmF3ZGF0YSAlPiUgCiAgZmlsdGVyKGdlbm90eXBlICE9ICJDUyBmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoZ2Vub3R5cGUpICU+JSAKICBncm91cF9ieSh1bmlxdWVfZmx5KSAlPiUgCiAgc3VtbWFyaXNlKGdlbm90eXBlID0gdW5pcXVlKGdlbm90eXBlKSwKICAgICAgICAgICAgcmlnaHRfd2luZ19pbmRleCA9IDEwMCpzdW0od2luZ19yX2FuZ19fcmFkW2NvdXJ0c2hpcF93aW5kb3coaW5wdXQpXT4oNDAqcGkvMTgwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBUUlVFKS8KICAgICAgICAgICAgICBsZW5ndGgoRnJhbWVbY291cnRzaGlwX3dpbmRvdyhpbnB1dCldCiAgICAgICAgICAgICAgICAgICAgICkpICU+JQogIGdncGxvdChhZXMoeD1nZW5vdHlwZSx5PXJpZ2h0X3dpbmdfaW5kZXgpKSArCiAgICBnZW9tX2JveHBsb3QoKQpnZ2FycmFuZ2UocGxvdGxpc3QgPSBsaXN0KHAxLHAyLHAzKSwKICAgICAgICAgIGxhYmVscyA9IGMoIndpbmcgaW5kZXgiLCJsZWZ0IHdpbmciLCJyaWdodCB3aW5nIiksCiAgICAgICAgICBoanVzdCA9IC0wLjYsCiAgICAgICAgICB2anVzdCA9IDIsCiAgICAgICAgICBuY29sID0gMywKICAgICAgICAgIG5yb3cgPSAxKQoKYGBgCgoKCgoKCgoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTR9CnAxIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBzdW1tYXJpc2UoZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpLAogICAgICAgICAgICB3aW5nX2luZGV4ID0gMTAwKnN1bShtYXhfd2luZ19hbmdfX3JhZFt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqNjAwKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdPig0MCpwaS8xODApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYS5ybSA9IFRSVUUpLwogICAgICAgICAgICAgIGxlbmd0aChGcmFtZVt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqNjAwKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgICAgICAgICkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUseT13aW5nX2luZGV4KSkgKwogICAgZ2VvbV9ib3hwbG90KCkKcDIgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KGdlbm90eXBlKSAlPiUgCiAgZ3JvdXBfYnkodW5pcXVlX2ZseSkgJT4lIAogIHN1bW1hcmlzZShnZW5vdHlwZSA9IHVuaXF1ZShnZW5vdHlwZSksCiAgICAgICAgICAgIGxlZnRfd2luZ19pbmRleCA9IDEwMCpzdW0od2luZ19sX2FuZ19fcmFkW3doaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCk6aWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pID4gd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pIDw9ICh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSo2MDApKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF08KC00MCpwaS8xODApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYS5ybSA9IFRSVUUpLwogICAgICAgICAgICAgIGxlbmd0aChGcmFtZVt3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApOmlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA+IHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh3aGljaC5tYXgoU21vb3RoZWRDb3B1bGF0aW9uKSA8PSAod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqNjAwKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4oKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KndpbmQpKSxtYXgoRnJhbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgICAgICAgICkpICU+JQogIGdncGxvdChhZXMoeD1nZW5vdHlwZSx5PWxlZnRfd2luZ19pbmRleCkpICsKICAgIGdlb21fYm94cGxvdCgpCnAzIDwtIGFsbF9yYXdkYXRhICU+JSAKICBmaWx0ZXIoZ2Vub3R5cGUgIT0gIkNTIGZlbWFsZSIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBzdW1tYXJpc2UoZ2Vub3R5cGUgPSB1bmlxdWUoZ2Vub3R5cGUpLAogICAgICAgICAgICByaWdodF93aW5nX2luZGV4ID0gMTAwKnN1bSh3aW5nX3JfYW5nX19yYWRbd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPD0gKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXT4oNDAqcGkvMTgwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBUUlVFKS8KICAgICAgICAgICAgICBsZW5ndGgoRnJhbWVbd2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKTppZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPiB3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uod2hpY2gubWF4KFNtb290aGVkQ29wdWxhdGlvbikgPD0gKHdoaWNoLm1heChTbW9vdGhlZENvdXJ0c2hpcCkrKDI1KjYwMCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWNoLm1heChTbW9vdGhlZENvcHVsYXRpb24pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbigod2hpY2gubWF4KFNtb290aGVkQ291cnRzaGlwKSsoMjUqd2luZCkpLG1heChGcmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluKCh3aGljaC5tYXgoU21vb3RoZWRDb3VydHNoaXApKygyNSp3aW5kKSksbWF4KEZyYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgICAgICAgICApKSAlPiUKICBnZ3Bsb3QoYWVzKHg9Z2Vub3R5cGUseT1yaWdodF93aW5nX2luZGV4KSkgKwogICAgZ2VvbV9ib3hwbG90KCkKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gbGlzdChwMSxwMixwMyksCiAgICAgICAgICBsYWJlbHMgPSBjKCJ3aW5nIGluZGV4IiwibGVmdCB3aW5nIiwicmlnaHQgd2luZyIpLAogICAgICAgICAgaGp1c3QgPSAtMC42LAogICAgICAgICAgdmp1c3QgPSAyLAogICAgICAgICAgbmNvbCA9IDMsCiAgICAgICAgICBucm93ID0gMSkKYGBgCgoKCgoKCgoKCgpgYGB7cn0KYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihnZW5vdHlwZSAhPSAiQ1MgZmVtYWxlIikgJT4lIAogIGZpbHRlcihnZW5vdHlwZSA9PSAiRCIpICU+JSAKICBncm91cF9ieShnZW5vdHlwZSkgJT4lIAogIGdyb3VwX2J5KHVuaXF1ZV9mbHkpICU+JSAKICBjYWxjdWxhdGVfaW5kaWNlcyhmZWF0dXJlID0gIm1heF93aW5nX2FuZ19fcmFkIixqYWFiYSA9IEZBTFNFLHRocmVzaCA9ICgyNSpwaS8xODApKQpgYGAKCgoKCgoKYGBge3J9CnRlc3QgPC0gYWxsX3Jhd2RhdGEgJT4lIAogIGZpbHRlcihGaWxlTmFtZSA9PSAiTWVnYW4tMjAxOV8wM18wNl9Db3VydHNoaXAtRHN4VmdsdXRUTlRfTWFsZV8xMjM0XzIiKSAlPiUgCiAgZmlsdGVyKElkID09IDM2KSAKYGBgCgoKYGBge3J9CmNhbGN1bGF0ZV9pbmRpY2VzKGlucHV0ID0gdGVzdCxmZWF0dXJlID0gIldpbmdHZXN0dXJlIixqYWFiYSA9IFRSVUUpCmBgYAoKCgpgYGB7cn0KY2FsY3VsYXRlX2luZGljZXMoaW5wdXQgPSB0ZXN0LGZlYXR1cmUgPSAibWF4X3dpbmdfYW5nX19yYWQiLGphYWJhID0gRkFMU0UsdGhyZXNoID0gKDI1KnBpLzE4MCkpCmBgYAoKCgoKYGBge3J9CmNhbGN1bGF0ZV9pbmRpY2VzKGlucHV0ID0gdGVzdCxmZWF0dXJlID0gIm1heF93aW5nX2FuZ2xlX19yYWQiLGphYWJhID0gRkFMU0UsdGhyZXNoID0gKDI1KnBpLzE4MCkpCmBgYAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK